I am participating in the nuggets Community game creative submission Contest. For details, please see: Game Creative Submission Contest

It was ten years ago ten years ago

My hometown is a village in Linyi, Shandong province. I remember when I was a child, there were a lot of things to play, one of which I like very much, that is chess.

The word “chess”, many people first feel is very elegant, because it belongs to “qin, chess, calligraphy and painting” one. But in the countryside, it can break your imagination.

First of all, who plays chess? They were all old men in the countryside, usually in the streets under the winter sun or in the shade under the summer sun, unable to work at this time of year, with nothing to do. They were unshaven and unwashed, sitting on dirt floors and laying straw with bricks. They laid out lines on the ground for a chessboard, and used stones and sticks as pieces for a whole morning. Then, what do they play? Go? Chess? Sorry, that needs professional instruments, they play chess can not be restricted by time, space, easy to, the name is dialect, such as: “four”, “six”, “suffocate cow” and so on.

When I was a teenager, I would gather together with the old men to watch chess. One of my favorite chess games is called “The big cannon small soldier”.

Later, I went to school in the city and learned software programming. When I graduated from college, I was in my twenties. I missed the old days, so I put “Big Shelling Little Soldier” on my smartphone, and I gave it a high-end name: Bing Jiangqi.

Pawn chess line, and not too much attention. Because that was my childhood, not someone else’s. So there was another decade of silence.

Ten years later, when I was in my thirties, it happened that the Nuggets held such an activity. I planned to re-show the “pawn chess” to the net friends and publish the rules, algorithms and source code to commemorate my twenty years of youth.

Second, pawn will display chess

The following is the main interface of pawn chess. If you want to experience it, you can get it at the end of the article. The entire installation package is only 1.5m in size, without any permissions.

2.1 Board and Layout

The board is six rows and six columns, with a total of 36 crossing points. The crossing points are the areas where the pieces move.

Two of them are white, horizontally side by side in the center of the next 3 bars. Black (pawn) 18, spread all positions in the top three horizontal.

2.2 Moves and rules

Because there are many fewer pawns (black), the first move (white) is made as an opening.

2.2.1 Will (White) move

General (white), mounted on a war horse, armed with a spear, can behead soldiers from a distance (black).

As a rule, only one space is allowed to kill an enemy.

It can only move 1 square at a time when there are no pawns left to kill. It likes to kill two objects in one move. The local language of this move is called: a pull two view son, said to pull down, look at the two pieces, the other party to lose, their victory.

The victory of the general (White) is to take all the pieces of the opponent and kill them.

2.2.2 Moves of pawn (black)

The pawn (black) is weak and can be killed at will, but can form a wall of human flesh, relying on the strength of the team to win.

The pawn (black) can only move one space at a time, and there is no danger of tying (White) close together, and cornering (black) to nowhere is considered victory.

2.2.3 Game features

The game supports single game (man-machine battle), multiplayer game (everyone battle), click to enter. You can start new games, choose your identity, and map.

A single player game (man-machine versus machine) can be played with a robot.

In the course of the game, support unlimited repent moves.

Three, focus on the implementation of the code

The source code of this game has been completely open, if you need to download the address at the end of the file.

The source code can be run in Android Studio, simple, with annotations.

Due to the extensive content, only some key codes are explained here.

3.1 Draw the chess game

First, we create a GameView class, which inherits from View and is the main class related to the game interface.

public class GameView extends View {

    /** ** /
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        clearCanvas(canvas);    // Empty the canvas
        drawChessBoard(canvas); // Draw the checkerboard
        drawQiZi(canvas);       // Draw the chess pieces}}Copy the code

Rewrite the onDraw method to draw graphics on the interface.

3.1.1 Drawing a Board

First, determine how many lines to draw. For example, if you want to draw 6 lines (6 vertical and 6 horizontal), loop 6 times, spacing each time, and draw horizontal and vertical lines.

/** * draw the checkerboard **@param canvas
 */
private void drawChessBoard(Canvas canvas) {
    for (int i = 0; i < lineNumber; i++) {
        canvas.drawLine(startX, startY + cellWidth * i, startX + cellWidth * (lineNumber - 1), startY + cellWidth * i, paint);
        canvas.drawLine(startX + cellHeight * i, startY, startX + cellHeight * i, startY + cellHeight * (lineNumber - 1), paint); }}Copy the code

3.1.2 Drawing Chess pieces

Here is the code to draw the pieces:

private void drawQiZi(Canvas canvas) {
    Bitmap qizi = null;
    for (int i = 0; i < map.length; i++) {// Draw the chess pieces according to the arrangement in the map, according to the line
        for (int j = 0; j < map[i].length; j++) {// Draw the chess pieces according to the arrangement in the map, according to the column
            int type = map[i][j];// Get the type of the piece
            if(type ! = RoleBean.ROLE_BLANK) {// If not blank
                if (type == RoleBean.ROLE_GENERAL) {/ / is general
                    qizi = img_balu;// Set the current piece to the general's piece
                } else if (type == RoleBean.ROLE_SOLDIER) {/ / is a soldier
                    qizi = img_guizi;// Set the current piece to the soldier's piece
                }
                int[] xy = getPointXyByCellXy(i, j, qizi);
                int x = xy[0];// Set the coordinates of the pieces
                int y = xy[1];
                canvas.drawBitmap(qizi, x, y, paint);/ / draw pieces
            }//end  (type != ROLE_BLANK)
        }//end map[i].length
    }//end map.length
}
Copy the code

First define a Bitmap, whether it is a pawn (black) or a pawn (white), where it is positioned, and then assign values according to logic.

The first loop map is a map that shows where the various pieces are.

// 5 horizontal and 5 vertical maps
public static int[][] Map_5 = {
         {1.1.1.1.1}
        ,{1.1.1.1.1}
        ,{0.0.0.0.0}
        ,{0.2.0.2.0}
        ,{0.0.0.0.0}};// 6 horizontal and 6 vertical maps
public static int[][] Map_6 = {
         {1.1.1.1.1.1}
        ,{1.1.1.1.1.1}
        ,{1.1.1.1.1.1}
        ,{0.0.0.0.0.0}
        ,{0.0.2.2.0.0}
        ,{0.0.0.0.0.0}};// 7 horizontal and 7 vertical maps
public static int[][] Map_7 = {
         {1.1.1.1.1.1.1}
        ,{1.1.1.1.1.1.1}
        ,{1.1.1.1.1.1.1}
        ,{1.1.1.1.1.1.1}
        ,{0.0.0.0.0.0.0}
        ,{0.0.2.2.2.0.0}
        ,{0.0.0.0.0.0.0}};Copy the code

As shown above, the two-dimensional array corresponds exactly to the vertical and horizontal lines of the board, where the elements “1” represent pawns (black), “2” represent generals (white), and “0” represent empty positions. Draw each element on the board in a loop.

Int [] xy = getPointXyByCellXy(I, j, qizi); getPointXyByCellXy(I, j, qizi); Calculates the (x,y) coordinates of the piece drawn under the current View. As we know, if you want to draw a picture on Canvas, you need to provide horizontal and vertical coordinates, which refer to the coordinates of the upper left corner of the image. So, even though we know that row 1, column 1 is a black, it’s going to take us a little bit of trouble to draw it exactly.

Here is the detailed code:

/** * Returns the physical coordinates ** on the View based on the number of rows the pieces are in@paramCellX The spacing of the horizontal axis of each cell *@paramCellY The spacing of the vertical axis of each cell *@return* /
public int[] getPointXyByCellXy(int cellX, int cellY, Bitmap bitmap) {
    int x = 0, y = 0;
    if(bitmap ! =null) {
        x = startX + cellY * cellWidth - bitmap.getWidth() / 2;
        y = startY + cellX * cellHeight - bitmap.getHeight() / 2;
    } else {
        x = startX + cellY * cellWidth;
        y = startY + cellX * cellHeight;
    }
    return new int[]{x, y};
}
Copy the code

3.2 Rules of move

We have already seen that the pawn (black) and the general (White) can only move one box at a time, but the general (white) has the privilege of being able to directly kill the pawn (black) if there is a gap between the pawn (black) and the pawn (black).

So how do these rules translate into code? It’s a lot more complicated than that.

The following ChessRule class, which is mainly used for rule management, defines some attributes:

public class ChessRule {

   private int[][] map;// The layout of the board
   private int fromX; // Start position X
   private int fromY;// Start position Y
   private int toX;// The destination position is X
   private int toY;// The destination position is Y
   private int moveChessID;// What is the starting position
   private int targetID;// What is the destination...Copy the code

Let’s go from simple to difficult, and first look at the logic of pawn (black).

3.2.1 The logic of pawn (black) moves

The pawn (black) moves very simply, one square at a time. But when it comes to code, things get a lot more complicated.

/** * Determine if the soldier can move *@returnFalse does not allow move, true can move */
public  boolean canMove(a){

   if (fromX < 0 || fromX > (lineNumber-1) || fromY < 0 || fromY > (lineNumber-1)) {// if the X-axis is off the screen, do not move it
      return false;
   }
   
   if (toX < 0 || toX > (lineNumber-1) || toY < 0 || toY > (lineNumber-1)) {// if the Y axis is off the screen, do not move it
      return false;
   }
   
   if(fromX==toX && fromY==toY){
       //3. The destination is the same as the starting point
      return false;
   }
   
   if((Math.abs(fromY - toY) + Math.abs(toX - fromX)) > 1) {// If the step size exceeds 1, do not move
      return false;
   }
   
   if(map[toY][toX]! =0) {//5, if there is a move at the end, do not move
      return false;
   }
   
   // Otherwise, return true to move
   return true;
   
} 
Copy the code

Did the guy say it would happen?

Of course! Because you can’t limit what users can do.

For example, if we block out the code for cases 4 and 5, it will appear, and pieces will fly and kill at will.

Writing programs is more about handling exceptions, so that no matter what the user does, only the rules matter.

3.2.2 Logic of moving (white)

The move of the general (white) is similar to the move of the pawn (black) in that it moves one square at a time. But in addition, it has another feature, that is, if there is an enemy in every space, it can move 2 Spaces at a time, and take the enemy’s place.

As a result, a lot of extra code is added:

/** * Determine whether the general can move *@returnFalse does not allow move, true can move */
public  boolean canMove(a){

    ……
    
    moveChessID = map[fromY][fromX];// Get the starting piece
    targetID = map[toY][toX];// Take the end piece
    if(isSameSide(moveChessID,targetID)){
        // If both start and end are people, do not move
        // Because it can eat seeds, but not by itself, it needs to be judged
       return false;
    }
    
    if (targetID == 0) {
        // If the general's destination is open space
       if(Math.abs(fromY - toY)  + Math.abs(toX - fromX) > 1) {// More than one grid, cannot move
          return false}}else{ // The general's destination is not an open space, there is an investigation of his own people, this must be the enemy
       if(fromY! =toY && fromX! =toX){// If it is a slash, do not move
          return false;
       }
       if(toY == fromY){
           // Walk sideways
          if(Math.abs(toX - fromX) ! =2) {// Cannot move if the distance from the target enemy is not 2
             return false;
          }
          if(fromX > toX){
              // Go left, no space in between, can't move
             if(map[toY][toX+1] != 0) {return false; }}else{// Go to the right, no space in the middle, can not move
             if(map[toY][toX-1] != 0) {return false; }}}if(toX == fromX){
           // Walk vertically
          if(Math.abs(toY - fromY) ! =2) {// Cannot move if the distance from the target enemy is not 2
             return false;
          }
          if(toY > fromY){
              // Go down, no space in the middle, can't move
             if(map[toY-1][toX] ! =0) {return false; }}else{// Go up, no space in the middle, can't move
             if(map[toY+1][toX] ! =0) {return false; }}}}// Otherwise, it can be moved
    return true;
}
Copy the code

3.2.3 Visual logic of regret and move

Repent, is back records. Well, we have to record every step before we can go back.

So, in GameView, there is a variable called allSteps that holds the chess history, which is a list of two-dimensional arrays.

public class GameView extends View {...public ArrayList<int[][]> allSteps;

}
Copy the code

Earlier, we introduced that the chess pieces are based on the map. A map is also defined as a two-dimensional array, such as the following:

// 5 horizontal and 5 vertical maps
int[][] Map_5 = {
     {1.1.1.1.1}
    ,{1.1.1.1.1}
    ,{0.0.0.0.0}
    ,{0.2.0.2.0}
    ,{0.0.0.0.0}};Copy the code

When the game changes, it must be a change in position or number of pieces. For example, if 2 (general) eats 1 (soldier) in the opening, the situation will look like this:

// The situation after the first step
int[][] step1 = {
     {1.1.1.1.1}
    ,{1.2.1.1.1}
    ,{0.0.0.0.0}
    ,{0.0.0.2.0}
    ,{0.0.0.0.0}};Copy the code

Allsteps.add (step1) once for each move. When repenting, execute allsteps.remove (size-1). Then, refresh the interface, you have achieved the visual update of the chess game.

3.3 Players and winning and losing

Object oriented programming, you have to have objects.

In this case, the general and the soldier, both players, belong to different roles. So, we’re going to have a BasePlayer class.

/** * Player base class */
public class BasePlayer {

   GameView gameView; // Game view
   int playerID; // Identity, general or soldier
   
   // Which move was chosen, where to go, -1 means not chosen
   public int selectX = -1, selectY = -1, targetX = -1, targetY = -1; 
   public int selectID = -1, targetID = -1; 
   
   public boolean isFocus = false; // Check whether the checkers are selected
   private boolean isEnable = false;// Whether the player can control, you can not move when the opponent moves
   
   // constructor
   public BasePlayer(GameView gameView, int playerID){
      this.gameView = gameView; // You are facing a chess game
      this.playerID = playerID; // Your identity
   }
   
   ……
   
}
Copy the code

3.3.1 Selecting and moving chess pieces

When the user touches the board from GameView, we can tell which piece the user clicked based on the drawing logic.

If you can’t imagine, I can paste the code:

/** * convert to the number of rows and columns corresponding to the checkerboard points ** based on the physical coordinates clicked@paramE Touch event *@return* /
public int[] getPos(MotionEvent e) {
    // Convert the coordinates to the dimensions of the array
    int[] pos = new int[2];
    double x = e.getX();// Get the x coordinate of the clicked position
    double y = e.getY();// Get the y coordinate of the clicked position
    
    int d = img_qizi.getHeight() / 2;
    if(e.getX() > startX - d && e.getX() < startX + cellWidth * lineNumber + d && e.getY() > startY - d && e.getY() < startY +  cellWidth * lineNumber + d) {// click on the checkerboard
        pos[0] = Math.round((float) ((y - startY) / cellHeight));// Get the row
        pos[1] = Math.round((float) ((x - startX) / cellWidth));// Get the column
    } else {// Click when the position is not checkerboard
        pos[0] = -1;// Set the location to unavailable
        pos[1] = -1;
    }
    return pos;// Return the coordinate array
}
Copy the code

After the user’s pinkie finger is pressed, it gets the information about the clicked piece and passes it to the Play (int[] pointIJ) method of BasePlayer, which selects the piece.

/** * According to the user click, select chess *@paramPointIJ Click position */
public void play(int[] pointIJ){

   int i = pointIJ[0];
   int j = pointIJ[1];
   
   if(i ! = -1&& j ! = -1) {// If you select valid pieces
      if (isFocus) {// Selected before
         if(gameView.map[i][j] ! = selectID) {// Then choose not their own pieces
            // It means you can either eat or move a space
            targetX = i;
            targetY = j;
            targetID = gameView.map[i][j];
            ChessRule cr = new ChessRule(gameView.map, selectY, selectX, targetY, targetX);
            if (cr.canMove()) {
               ChessMove cm = new ChessMove(selectID, selectY, selectX, targetID, targetY, targetX, 0);
               runPoint(cm);
               selectX = -1;
               selectY = -1;
               selectID = -1;
               targetX = -1;
               targetY = -1;
               targetID = -1;
            }else{
               selectX = -1;
               selectY = -1;
               selectID = -1; } } isFocus = ! isFocus; }else{
          // You must choose your own piece for the first time. You can't choose blank and opponent's piece for the first time
         // Select the starting point
         if (gameView.map[i][j] == playerID) {
            // Play sound effects, select the "click" sound of the piece
            SoundUtil.playSound(SoundUtil.SOUND_SELECT);
            selectX = i; 
            selectY = j;
            selectID = gameView.map[selectX][selectY];
            targetX = -1; 
            targetY = -1;
            targetID = -1; isFocus = ! isFocus; }// end if (gameView.map[i][j] == playerID)
      }//else{
   }//end if (i ! = -1 && j ! = 1) {
}
Copy the code

Its main purpose is to deal with what happens after the player clicks on a piece, even though you click on just one piece, it can involve a lot of things:

  1. This is the first choice, so I’m going to pick it.
  2. Select a piece before, this time click the piece again, give up the selection.
  3. Select one piece before, this time click another piece, change the choice.
  4. Select a piece before, this time click another piece, to eat.
  5. Select a piece before, this time click blank, to move.

The above code is basically the logic described.

With a choice piece, you know what it should do next. Whether it’s walking or eating, just update the map, record the history, and redraw the board.

3.3.2 Judgment of winning or losing

Winning or losing is relative. If white wins, it’s the same thing as black losing.

Here, let’s take winning.

What are the conditions under which will (White) win? It kills all the pawns, and the number of pawns becomes zero.

/** * General player victory *@return* /
public boolean winChess(a){
   
   int count=0;
   for (int i = 0; i < gameView.map.length; i++) {
      for (int j = 0; j < gameView.map[i].length; j++) {
         if (gameView.map[i][j] == RoleBean.ROLE_SOLDIER) {// If a pawn is a soldier
            count++;// The quantity is increased by 1}}}if (count == 0) {
      return true;
   }
   
   return false;
}
Copy the code

Now, what are the conditions for a pawn (black) to win? Congratulations you will answer, that is: will (white) blocked, will (white) can move the number of 0.

In “2.2.1 Moves of White”, we describe the conditions under which white can be moved. If it returns false in all cases, it has no choice.

// Go up 1 space
ChessRule chessRule10 = new ChessRule(map, x, y, x, y-1);
if(chessRule20 canMove ()) {... }// Go down 1 space
ChessRule chessRule20 = new ChessRule(map, x, y, x, y+1);
if(chessRule10 canMove ()) {... }// Go one space to the left
ChessRule chessRule30 = new ChessRule(map,  x, y, x-1, y);
if(chessRule30 canMove ()) {... }// Go one space to the right
ChessRule chessRule40 = new ChessRule(map,  x, y, x+1, y);
if(chessRule40 canMove ()) {... }// Go down 2 Spaces
ChessRule chessRule102 = new ChessRule(map, x, y, x, y+2);
if(chessRule102 canMove ()) {... }// Go up 2 Spaces
// Go left 2 squares
// Go 2 squares to the right

Copy the code

3.4 AI man-machine battle

When I was in college, I learned shanzhai computer programming. At that time, there was man-machine war in the game, where man-machine war began to be called artificial intelligence. In fact, it was all kinds of if and else judgment.

Mine, too.

However, there are some ideas worth learning, such as why this step is better than that step, what is your judgment logic?

First of all, a ComputerPlayer is also a player, so you need to create a ComputerPlayer class that inherits from the BasePlayer class, which has all of the basic player behavior of choosing, playing, replaying, and winning.

/** * Computer player class */
public class ComputerPlayer extends BasePlayer {

   GameView gameView;
   int playerID;
   AIPlayer aiPlayer; 
   
   public ComputerPlayer(GameView gameView, int playerID) {
      super(gameView, playerID);
      this.gameView = gameView;
      this.playerID = playerID;
      aiPlayer = new AIPlayer();
   }

   @Override
   public void play(int[] pointIJ) {
      // Rewrite the move method
      ChessMove cm = aiPlayer.searchAGoodMove(gameView.map, playerID);
      runPoint(cm);
   }
   
 ……  
 
 }
Copy the code

The difference is that normal players click on the screen to select pieces, while computer players automatically count the selected pieces.

So, you see ComputerPlayer’s paly method has been rewritten. Instead of using any screen click to transfer position coordinates, it simply clicks on the screen and calls runPoint to move depending on the current state of the game and who you are.

The key point is the method of AIPlayer searchAGoodMove to find the best move.


/** * artificial intelligence */ 
public class AIPlayer {

    // Evaluate moves and choose the best move
    public ChessMove searchAGoodMove(int[][] qizi, int chessRole){// Query for a good move
            List<ChessMove> ret = allPossibleMoves(qizi,chessRole);// Generate all moves
            int id = bestsorce(qizi,ret,chessRole);/ / to score
            return ret.get(id); // Returns the best result
    }
	
    // Evaluate moves and select the best move;
    public int bestsorce(int[][] qizi,List<ChessMove> ret, int chessRole){}... }Copy the code

The best way, in fact, is a principle, that is to “seek advantages and avoid harm”, this way will certainly make our side stronger, let the enemy weaken.

Its logic consists of two steps, finding all the moves, and then using the algorithm to score each move, the one with the highest score is the best move.

General robot so-called “elementary”, “intermediate”, “advanced” computer chess players, in fact, corresponding to the different points of the move.

3.4.1 Find all moves first

Finding all moves is very simple, as long as traversing all the positions of the current board, if there are chess pieces in the position, judge what identity is, and then according to the identity according to the rules of the move, exhaustive selection of each situation, for each step of the rule verification, if the verification passes, then join the list of moves.

/** * get all moves *@paramMap Current situation map *@paramChessRole role *@return* /
public List<ChessMove> allPossibleMoves(int[][] map, int chessRole){

   List<ChessMove> moveList =new ArrayList<ChessMove>();// Generate all moves

   // Loop through each grid to find the pieces
   for (int y = 0; y < lineNumber; y++){
      for (int x = 0; x < lineNumber; x++){
         // Loop through all positions
         int chessman = map[y][x];
         if (RoleBean.ROLE_SOLDIER == chessman){// If you are a soldier
            // Can you go down 1 space
            ChessRule chessRule1 = new ChessRule(map, x, y, x, y+1);
            if(chessRule1.soldierCanMove()){ // If yes, add it to the list
               moveList.add(new ChessMove(chessman, x, y, map[x][y+1], x, y+1.0));
            }
            // Go up 1 space...// Go one space to the left...// Go one space to the right... }else if (RoleBean.ROLE_GENERAL == chessman){// If you are a general
            // Can you go down 1 space
            ChessRule chessRule10 = new ChessRule(map, x, y, x, y+1);
            if(chessRule10.generalCanMove()){ // If yes, add it to the list
               moveList.add(new ChessMove(chessman, x, y, map[x][y+1],  x, y+1.0));
            }
            // Go up 1 space...// Go one space to the left...// Go one space to the right...// Go down 2 Spaces...// Go up 2 Spaces...// Go left 2 squares...// Go 2 squares to the right... }}}...return moveList;
}
Copy the code

You can write a separate method for each identity. Because this is my graduation when I wrote, put all identities together, to the inside again use if, esle to judge. This way is not good maintenance, writing is not standard, please great gods forbearance.

3.4.2 Score each move

Given all the moves, which one should the robot choose? That’s what bestSorce does.


/** * Evaluate moves and select the best move *@paramMap Current situation map *@paramRet All moves *@paramChessRole role *@returnIndex of the best moves */
public int bestSorce(int[][] map,List<ChessMove> ret, int chessRole){...return bestIndex;
 }
Copy the code

For the pawn (black), its purpose is to block the pawn (White).

If it takes this move, the opponent blocked, win, then this move is the best move.

If you can’t defeat the enemy in one move, this move gives the general fewer moves, reducing the enemy’s range of movement, and is the best move compared to a lost move.

Let’s take a look at how the code can find the best move for a pawn (black) :

// Loop through all your moves, taking each step to judge
// If you do make this move, determine how many moves your opponent has left
List<ChessMove> list =  allPossibleMoves(testqizi, RoleBean.ROLE_GENERAL);

if (list == null) { // If your opponent can't find his way, he is blocked
    return i; // Return this step as the best move
}

int count = list.size();
if (count < general_min_steps) {// If this move embarrasses the opponent more than any other move
  general_min_steps = count; // Record the distress value and compare it next time
  bestID = i; // Record the ID, which is currently the best way to go
}
Copy the code

The above operation is to find the minimum possible moves on allPossibleMoves.

Now let’s talk about how to find the best move. The purpose of the pawn (White) is to eat up the pawn (black) pieces.

If, in this move, the number of pawns (black) becomes zero, then this is the best move.

If it can’t defeat the enemy in one move, its move reduces the number of pawns (black) and weakens the number of enemies, making it the best move compared to losing a move. In addition, under the same conditions, even if a step of chess, also have to make their own more and more open range of activities, which is a relatively better move.

// Loop through all your moves, taking each step to judge
// After you have taken this step, decide how many steps you have left
List<ChessMove> list =  allPossibleMoves(testqizi, RoleBean.ROLE_GENERAL);
int mySteps = 0;
if(list ! =null) {
    mySteps = list.size(); // Record the number of steps you take
}

int soldierCount = chessRule.getSoldierCount(); // The number of opponents left

if (soldierCount <= minSoldierCount) {// If this step can reduce the number of soldiers, it will be preferred
    minSoldierCount = soldierCount; // Record the current minimum number of soldiers
    bestID = i;// Select best
    // Under the same conditions, this step by the general will not only reduce the number of soldiers, but also enlarge his range of action
    if (mySteps >= myMaxSteps) {
       myMaxSteps = mySteps;
       bestID = i;// Select best}}Copy the code

The next decade

Said above, is the most basic, the most simple small white way, without any cunning, and just graduated at that time I as naive.

In fact, you should also think about what happens after the next step, or even a few steps.

In the case of pawn (Black), this move may seem to block the general (White), but it is a partial victory. Because the next move will eat you.

In the case of the general (White), this move may seem to take a pawn (black), but it is also a partial victory. Because the next pawn (black) will surround you.

Beyond that, there are many tricks. For example, the pawn (black) deliberately killed, so please (White) into the urn, blocked it.

Then the general (White) needs to figure out what will happen to the back, even if there will be reversals behind the back.

All of the above, once reflected in the program, is very complicated, complex to infinite if and else description.

If you want to write this game well, you have to be an expert at chess, and you have to be an expert at programming.

But from now on, with deep learning and neural networks, you can simply learn the rules of chess and the structure of a network model, and leave the rest to machines to learn, and with a few hours of training, you can build a program with 100 years of power.

Artificial intelligence era of the game, we hurry to participate in it.

Don’t wait for tomorrow. Start now. Let’s study together.

Game installation package apK download address and project source code address:

Github.com/xitu/game-g… Under the [pawn chess -TF boy] folder.

Special note: The installation package is only 1.5m in size, without any permission request. Source code in addition to SDK, did not reference any third party package, all handwritten code, is a beginner's textbook game programming.Copy the code