English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Esempio di gioco di Gomoku semplice implementato in Android

Questo esempio spiega un semplice gioco di GoMoku realizzato con Android. Lo condivido con voi per riferimento, come segue:

Ho appena scritto un piccolo programma di GoMoku su Android, voglio condividerlo con voi.

Dopo averlo scritto, ho sentito che la SDK di Android, anche se utilizza Java, è molto diversa da Java ME.

Prima di tutto, la SDK di Android non implementa tutti gli standard Java ME, le applicazioni che erano in esecuzione su KJava non possono essere eseguite direttamente su Android.

Inoltre, la SDK di Android ha una grande quantità di API che sono proprie di Android, i programmatori devono conoscerle.

Il framework di sviluppo di Android è anche diverso dagli altri, è necessario impararlo.

Questo gioco di GoMoku è stato creato da me, basandomi sul Demo di Snake di Android e altri esempi, e aggiungendo le mie esigenze.

Tra cui la funzione di scacchiere, giocare a scacchi, determinare la vittoria o la sconfitta, e riavviare la partita. Al momento, non è stata implementata la funzione di intelligenza artificiale per muovere le pedine.

La funzione di schermo touch di Android è molto utile, l'altro giorno ho visto qualcuno dimostrare il G1, lo schermo touch è molto utile, e l'interfaccia "Window" di Android e la tenda "Shade", insieme al tocco, sembrano molto affascinanti.

Ehm, questo GoMoku utilizza anche lo schermo touch per muovere le pedine. Clicca su una posizione sulla scacchiera per posizionare le pedine sulla scacchiera.

Prima mettiamo un'immagine per vedere l'effetto.

Bene, ecco il codice:

/*
 * Five In a Row. (GoMoku)
 * Questo è un programma di GoMoku semplice, un esercizio personale, condiviso con tutti voi.
 * Spero di comunicare con tutti voi. Il mio GoogleTalk: lixinso <at> gmail.com
 *
 *
 */
//----------------------
// TBD: IA, revoca mossa
//---------------------
package lixinsong.game.gobang;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
// Questo è il programma principale, ereditato da Activity, che implementa il metodo onCreate.:
public class gobang extends Activity {
 GobangView gbv;
 /** Chiamato quando l'attività viene creata per la prima volta. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  gbv = (GobangView)this.findViewById(R.id.gobangview);
  gbv.setTextView((TextView)this.findViewById(R.id.text));
}

All'interno c'è R.id.gobangview definito in res come View.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <lixinsong.game.gobang.GobangView android:id="@+id/gobangview"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:text="aaaaa" tileSize="24" />
 <RelativeLayout
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_centerInParent="true" >
  <TextView
   android:id="@+id/text"
   android:text="hahahhaha"
   android:visibility="visible"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_centerInParent="true"
   android:gravity="center_horizontal"
   android:textColor="#ffff0000"
   android:textStyle="bold"
   android:textSize="24sp" />
  </RelativeLayout>
</FrameLayout>

五子棋的View

package lixinsong.game.gobang;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
/*棋盘一共10×10格
 * 棋盘居中
 *
 *
 *
 */
//public class GobangView extends View implements Runnable {
public class GobangView extends View{
 protected static int GRID_SIZE = 10;
 protected static int GRID_WIDTH = 30; // 棋盘格的宽度
 protected static int CHESS_DIAMETER = 26; // 棋的直径
 protected static int mStartX;// 棋盘定位的左上角X
 protected static int mStartY;// 棋盘定位的左上角Y
 private Bitmap[] mChessBW; // 黑棋和白棋
 private static int[][] mGridArray; // 网格
 boolean key = false;
 int wbflag = 1; //该下白棋了=2,该下黑棋了=1. 这里先下黑棋(黑棋以后设置为机器自动下的棋子)
 int mLevel = 1; //游戏难度
 int mWinFlag = 0;
 private final int BLACK=1;
 private final int WHITE=2;
 int mGameState = GAMESTATE_RUN; //游戏阶段:0=尚未游戏,1=正在进行游戏,2=游戏结束
 static final int GAMESTATE_PRE = 0;
 static final int GAMESTATE_RUN = 1;
 static final int GAMESTATE_PAUSE = 2;
 static final int GAMESTATE_END = 3;
 //private TextView mStatusTextView; // 根据游戏状态设置显示的文字
 public TextView mStatusTextView; // 根据游戏状态设置显示的文字
 private Bitmap btm1;
 private final Paint mPaint = new Paint();
 CharSequence mText;
 CharSequence STRING_WIN = "White win! /n Press Fire Key to start new game.";
 CharSequence STRING_LOSE = "Black win! /n Press Fire Key to start new game.";
 CharSequence STRING_EQUAL = "Cool! You are equal! /n Press Fire Key to start new Game.";
 public GobangView(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
  }
 public GobangView(Context context, AttributeSet attrs) { //Sembra che venga chiamato questo costruttore, perché non è quello precedente?
  super(context, attrs);
  this.setFocusable(true); //20090530
  this.setFocusableInTouchMode(true);
  init();
 }
 // Qui vengono disegnati i pezzi di scacchi, ma alla fine non sono stati disegnati con immagini, ma direttamente con cerchi. Perché le mie immagini non erano belle.
 // Inizializza i Bitmap delle pedine nere e bianche
 public void init() {
  mGameState = 1; //Imposta lo stato del gioco come iniziato
  wbflag = BLACK; //Inizialmente il giocatore azzurro gioca
  mWinFlag = 0; //Pulisci il segno di vittoria/sconfitta.
  mGridArray = new int[GRID_SIZE-1][GRID_SIZE-1];
  mChessBW = new Bitmap[2];
  Bitmap bitmap = Bitmap.createBitmap(CHESS_DIAMETER, CHESS_DIAMETER, Bitmap.Config.ARGB_8888);
  Canvas canvas = new Canvas(bitmap);
  Resources r = this.getContext().getResources();
  Drawable tile = r.getDrawable(R.drawable.chess1);
  tile.setBounds(0, 0, CHESS_DIAMETER, CHESS_DIAMETER);
  tile.draw(canvas);
  mChessBW[0] = bitmap;
  tile = r.getDrawable(R.drawable.chess2);
  tile.setBounds(0, 0, CHESS_DIAMETER, CHESS_DIAMETER);
  tile.draw(canvas);
  mChessBW[1] = bitmap;
 }
 public void setTextView(TextView tv){
  mStatusTextView =tv;
  mStatusTextView.setVisibility(View.INVISIBLE);
 }
 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  mStartX = w / 2 - GRID_SIZE * GRID_WIDTH / 2;
  mStartY = h / 2 - GRID_SIZE * GRID_WIDTH / 2;
 }
  @Override
 public boolean onTouchEvent(MotionEvent event){
  switch (mGameState) {
  case GAMESTATE_PRE:
   break;
  case GAMESTATE_RUN: {
    int x;
    int y;
    float x0 = GRID_WIDTH - (event.getX() - mStartX) % GRID_WIDTH;
    float y0 = GRID_WIDTH - (event.getY() - mStartY) % GRID_WIDTH;
    if (x0 < GRID_WIDTH / 2) {
     x = (int) ((event.getX() - mStartX) / GRID_WIDTH);
    else {
     x = (int) ((event.getX() - mStartX) / GRID_WIDTH) - 1;
    }
    if (y0 < GRID_WIDTH / 2) {
     y = (int) ((event.getY() - mStartY) / GRID_WIDTH);
    else {
     y = (int) ((event.getY() - mStartY) / GRID_WIDTH) - 1;
    }
    if ((x >= 0 && x < GRID_SIZE - 1)
      && (y >= 0 && y < GRID_SIZE - 1)) {
     if (mGridArray[x][y] == 0) {
      if (wbflag == BLACK) {
       putChess(x, y, BLACK);
       //this.mGridArray[x][y] = 1;
       if(checkWin(BLACK)){ //Se il pezzo nero ha vinto
        mText = STRING_LOSE;
        mGameState = GAMESTATE_END;
        showTextView(mText);
       } else if(checkFull()){//Se la scacchiera è piena
        mText = STRING_EQUAL;
        mGameState = GAMESTATE_END;
        showTextView(mText);
       }
       wbflag = WHITE;
      } else if (wbflag == WHITE) {
       putChess(x, y, WHITE);
       //this.mGridArray[x][y] = 2;
       if(checkWin(WHITE)){
        mText = STRING_WIN;
        mGameState = GAMESTATE_END;
        showTextView(mText);
       } else if(checkFull()){//Se la scacchiera è piena
        mText = STRING_EQUAL;
        mGameState = GAMESTATE_END;
        showTextView(mText);
       }
       wbflag = BLACK;
      }
     }
    }
   }
   break;
  case GAMESTATE_PAUSE:
   break;
  case GAMESTATE_END:
   break;
  }
  this.invalidate();
  return true;
 }
 @Override
 public boolean onKeyDown(int keyCode, KeyEvent msg) {
  Log.e("KeyEvent.KEYCODE_DPAD_CENTER", " " + keyCode);
  if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER){
   switch(mGameState){
   case GAMESTATE_PRE:
    break;
   case GAMESTATE_RUN:
    break;
   case GAMESTATE_PAUSE:
    break;
   case GAMESTATE_END:
   {//Gioco finito, premere il tasto CENTRO per continuare
    Log.e("Fire Key Pressed:::", "FIRE");
    mGameState = GAMESTATE_RUN;
    this.setVisibility(View.VISIBLE);
    this.mStatusTextView.setVisibility(View.INVISIBLE);
    this.init();
    this.invalidate();
   }
    break;
   }
  }
  return super.onKeyDown(keyCode, msg);
 }
 @Override
 public void onDraw(Canvas canvas) {
  canvas.drawColor(Color.YELLOW);
  // disegna il tavolo da scacchi
  {
   Paint paintRect = new Paint();
   paintRect.setColor(Color.GRAY);
   paintRect.setStrokeWidth(2);
   paintRect.setStyle(Style.STROKE);
   per (int i = 0; i < GRID_SIZE; i++) {
    per (int j = 0; j < GRID_SIZE; j++) {
     int mLeft = i * GRID_WIDTH + mStartX;
     int mTop = j * GRID_WIDTH + mStartY;
     int mRright = mLeft + GRID_WIDTH;
     int mBottom = mTop + GRID_WIDTH;
     canvas.drawRect(mLeft, mTop, mRright, mBottom, paintRect);
    }
   }
   // disegna il perimetro del tavolo da scacchi
   paintRect.setStrokeWidth(4);
   canvas.drawRect(mStartX, mStartY, mStartX + GRID_WIDTH*GRID_SIZE, mStartY + GRID_WIDTH*GRID_SIZE, paintRect);
  }
  // disegna pedine
  per (int i = 0; i < GRID_SIZE-1; i++) {
   per (int j = 0; j < GRID_SIZE-1; j++) {
    se(mGridArray[i][j] == BLACK){
     //通过图片来画
     //canvas.drawBitmap(mChessBW[0], mStartX + (i+1) * GRID_WIDTH - CHESS_DIAMETER/2 , mStartY + (j+1)* GRID_WIDTH - CHESS_DIAMETER/2 , mPaint);
     //通过圆形来画
      {
      Paint paintCircle = new Paint();
      paintCircle.setColor(Color.BLACK);}
      canvas.drawCircle(mStartX + (i+1) * GRID_WIDTH, mStartY + (j+1)* GRID_WIDTH, CHESS_DIAMETER/2, paintCircle);
     }
    }else if(mGridArray[i][j] == WHITE){
     //通过图片来画
     //canvas.drawBitmap(mChessBW[1], mStartX + (i+1) * GRID_WIDTH - CHESS_DIAMETER/2 , mStartY + (j+1)* GRID_WIDTH - CHESS_DIAMETER/2 , mPaint);
     //通过圆形来画
     {
      Paint paintCircle = new Paint();
      paintCircle.setColor(Color.WHITE);
      canvas.drawCircle(mStartX + (i+1) * GRID_WIDTH, mStartY + (j+1)* GRID_WIDTH, CHESS_DIAMETER/2, paintCircle);
     }
    }
   }
  }
 }
 public void putChess(int x, int y, int blackwhite){
  mGridArray[x][y] = blackwhite;
 }
 public boolean checkWin(int wbflag){
  for(int i = 0; i < GRID_SIZE - 1 ; i++ ) //i表示列(根据宽度算出来的)
   for(int j = 0; j < GRID_SIZE - 1; j++){//i表示行(根据高度算出来的)
    //检测横轴五个相连
    if(((i+4) < (GRID_SIZE - 1))&&
     (mGridArray[i][j] == wbflag) && (mGridArray[i+1][j] == wbflag) && (mGridArray[i + 2][j] == wbflag) && (mGridArray[i + 3][j] == wbflag) && (mGridArray[i + 4][j] == wbflag){
     Log.e("check win or loss:", wbflag + "win");
     mWinFlag = wbflag;
    }
    //asse verticale 5 connesse
    if(((j+4) < (GRID_SIZE - 1))&&
       (mGridArray[i][j] == wbflag) && (mGridArray[i][j+1] == wbflag)&& (mGridArray[i ][j+ 2] == wbflag) && (mGridArray[i ][j+ 3] == wbflag) && (mGridArray[i ][j+ 4] == wbflag)){
       Log.e("check win or loss:", wbflag + "win");
       mWinFlag = wbflag;
      }
    //sinistra in alto a destra in basso 5 connesse
    if(((j+4) < (GRID_SIZE - 1))&& ((i+4) < (GRID_SIZE - 1)) &&
       (mGridArray[i][j] == wbflag) && (mGridArray[i+1][j+1] == wbflag)&& (mGridArray[i + 2 ][j+ 2] == wbflag) && (mGridArray[i + 3][j+ 3] == wbflag) && (mGridArray[i + 4 ][j+ 4] == wbflag)){
       Log.e("check win or loss:", wbflag + "win");
       mWinFlag = wbflag;
      }
    //destra in alto a sinistra in basso 5 connesse
    if(((i-4) >= 0)&& ((j+4) < (GRID_SIZE - 1)) &&
       (mGridArray[i][j] == wbflag) && (mGridArray[i-1][j+1] == wbflag)&& (mGridArray[i - 2 ][j+ 2] == wbflag) && (mGridArray[i - 3][j+ 3] == wbflag) && (mGridArray[i - 4 ][j+ 4] == wbflag)){
       Log.e("check win or loss:", wbflag + "win");
       mWinFlag = wbflag;
      }
  }
  if( mWinFlag == wbflag){
   return true;
  } else
   return false;
 }
 public boolean checkFull() {
  int mNotEmpty = 0;
  per(int i = 0; i < GRID_SIZE -1; i++)
   for(int j = 0; j < GRID_SIZE - 1; j ++){}
    if(mGridArray[i][j] != 0) mNotEmpty +=1;
   }
  if(mNotEmpty == (GRID_SIZE-1)*(GRID_SIZE-1)) return true;
  else return false;
 }
 public void showTextView(CharSequence mT){
  this.mStatusTextView.setText(mT);
  mStatusTextView.setVisibility(View.VISIBLE);
 }
}

PS: Vi consiglio un altro gioco di Go in versione js di questo sito per riferimento (il suo AI è relativamente semplice).

Gioco di Go online:
http://tools.jb51.net/games/wuziqi

Per chi è interessato a ulteriori contenuti su Android, i lettori possono consultare le sezioni speciali di questo sito: 'Tutorial di introduzione e avanzamento dello sviluppo Android', 'Tecniche di debug e soluzioni di problemi comuni di Android', 'Sommarizzazione dell'uso dei componenti base di Android', 'Sommarizzazione delle tecniche di View di Android', 'Sommarizzazione delle tecniche di layout di Android' e 'Sommarizzazione dell'uso dei controlli di Android'.

Spero che questo articolo possa essere utile per la progettazione di applicazioni Android.

Dichiarazione: il contenuto di questo articolo è stato tratto da Internet, il copyright spetta ai rispettivi proprietari, il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, questo sito non detiene i diritti di proprietà, non è stato editato manualmente e non assume alcuna responsabilità legale. Se trovi contenuti sospetti di violazione del copyright, ti preghiamo di inviare una e-mail a: notice#oldtoolbag.com (al momento dell'invio dell'e-mail, sostituisci # con @) per segnalare, fornendo prove pertinenti. Una volta verificata, questo sito eliminerà immediatamente il contenuto sospetto di violazione del copyright.

Ti potrebbe interessare