翻转棋问题之“Flip Game”

本文介绍了一种通过深搜算法解决4x4棋盘上黑白格子转换为同色的最少操作步骤问题。利用枚举和状态检查,实现了对棋盘的翻转操作,最终输出最小步数或判断是否可行。

题目大意:

  输入4*4的棋盘,用 b 代表 黑色,w 代表 白色。

  输出能把这个棋盘变成同色的最少步数,不可能则输出 Impossible 

  样例: bwwb

      bbwb

      bwwb            -->    4

      bwww

解题思路:

  枚举每一种可能,使用深搜求解,不要忘了搜索的时候带上步数。

AC代码:

 1 import java.util.*;
 2 
 3 public class POJ1753{
 4 
 5     static boolean mark[][] = new boolean[8][8];
 6     static int step;
 7     static boolean is_OK;
 8 
 9     static boolean check(){
10         for(int ii = 1;ii < 5;ii ++){
11             for(int jj = 1;jj < 5;jj ++){
12                 if(mark[ii][jj] != mark[1][1]){ return false; }
13             }
14         }
15         return true;
16     }
17     
18     static void flip_them(int x,int y){
19         mark[x][y] = (!mark[x][y]);
20         mark[x + 1][y] = (!mark[x + 1][y]);
21         mark[x - 1][y] = (!mark[x - 1][y]);
22         mark[x][y + 1] = (!mark[x][y + 1]);
23         mark[x][y - 1] = (!mark[x][y - 1]);
24     }
25 
26     static void dfs(int x,int y,int steps){
27         if(steps >= step){
28             is_OK = check();
29             return ;
30         }
31         if(is_OK == true || x >= 5){return ;}
32         flip_them(x,y);
33         if(y < 4){dfs(x,y + 1,steps + 1);}
34         else {dfs(x + 1,1,steps + 1);}
35         flip_them(x,y);
36         if(y < 4){dfs(x,y + 1,steps);}
37         else {dfs(x + 1,1,steps);}    
38     }
39 
40     public static void main(String[] args){
41         Scanner sc = new Scanner(System.in);
42         while(sc.hasNext()){
43             is_OK = false;
44             for(int ii = 0;ii < 7;ii ++){
45                 for(int jj = 0;jj < 7;jj ++){ mark[ii][jj] = true; }
46             }
47             for(int i = 1;i <= 4;i ++){
48                 String t = sc.nextLine();
49                 for(int j = 1;j <= 4;j ++){
50                     if(t.charAt(j - 1) == 'b'){ mark[i][j] = true; }
51                     else{ mark[i][j] = false; }
52                 }
53             }
54             for(step = 0;step <= 16;step ++){
55                 dfs(1,1,0);
56                 if(is_OK == true){break;}
57             }
58             if(is_OK == true){System.out.println(step);}
59             else if(is_OK == false){System.out.println("Impossible");}
60         }
61     }
62 }

 

转载于:https://www.cnblogs.com/love-fromAtoZ/p/7551352.html

### Java 实现翻转(Reversi)的核心逻辑 翻转是一种策略型棋盘游戏,玩家轮流放置自己的子并尝试通过夹住对方的子来将其翻转为自己的一方。以下是基于提供的引用内容以及翻转基本规则设计的一个简单实现方案。 #### 游戏核心功能描述 1. **初始化棋盘** 使用二维数组表示棋盘状态,初始状态下中间四个位置有固定的黑白分布。 2. **判断合法移动** 需要验证当前玩家所选的位置是否可以翻转对手的子。如果无法翻转,则该步不合法[^2]。 3. **执行翻转操作** 如果某一步是合法的,则需要沿着八个方向逐一检查是否有可被翻转子,并完成相应的翻转动作。 4. **胜负判定** 当棋盘填满或者双方都无法继续下时,统计黑和白的数量决定胜者。 --- #### 初步代码框架 以下是一个简单的 Java 类结构用于模拟 Reversi 的部分功能: ```java public class Reversi { private static final int SIZE = 8; // 棋盘大小为 8x8 private char[][] board; private char currentPlayer; public Reversi() { this.board = new char[SIZE][SIZE]; initializeBoard(); this.currentPlayer = 'X'; // 默认先手为 X (黑色) } /** * 初始化棋盘 */ private void initializeBoard() { for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { board[i][j] = '.'; } } board[3][3] = 'O'; board[3][4] = 'X'; board[4][3] = 'X'; board[4][4] = 'O'; } /** * 打印棋盘 */ public void printBoard() { System.out.print(" "); for (int i = 0; i < SIZE; i++) { System.out.print(i + " "); } System.out.println(); for (int i = 0; i < SIZE; i++) { System.out.print(i + " "); for (int j = 0; j < SIZE; j++) { System.out.print(board[i][j] + " "); } System.out.println(); } } /** * 尝试放置子并翻转 * * @param row 行号 * @param col 列号 * @return 是否成功放置 */ public boolean placePiece(int row, int col) { if (!isValidMove(row, col)) { return false; } board[row][col] = currentPlayer; flipPieces(row, col); switchPlayer(); // 切换到下一个玩家 return true; } /** * 验证某个位置是否为合法走法 * * @param row 行号 * @param col 列号 * @return 是否合法 */ private boolean isValidMove(int row, int col) { if (row < 0 || row >= SIZE || col < 0 || col >= SIZE || board[row][col] != '.') { return false; } for (int dr = -1; dr <= 1; dr++) { for (int dc = -1; dc <= 1; dc++) { if (dr == 0 && dc == 0) continue; int r = row + dr, c = col + dc; if (r >= 0 && r < SIZE && c >= 0 && c < SIZE && board[r][c] != '.' && board[r][c] != currentPlayer) { while (r >= 0 && r < SIZE && c >= 0 && c < SIZE && board[r][c] != '.') { if (board[r][c] == currentPlayer) { return true; } r += dr; c += dc; } } } } return false; } /** * 翻转指定位置周围的子 * * @param row 行号 * @param col 列号 */ private void flipPieces(int row, int col) { for (int dr = -1; dr <= 1; dr++) { for (int dc = -1; dc <= 1; dc++) { if (dr == 0 && dc == 0) continue; List<int[]> toFlip = new ArrayList<>(); int r = row + dr, c = col + dc; while (r >= 0 && r < SIZE && c >= 0 && c < SIZE && board[r][c] != '.' && board[r][c] != currentPlayer) { toFlip.add(new int[]{r, c}); r += dr; c += dc; } if (r >= 0 && r < SIZE && c >= 0 && c < SIZE && board[r][c] == currentPlayer) { for (int[] pos : toFlip) { board[pos[0]][pos[1]] = currentPlayer; } } } } } /** * 切换当前玩家 */ private void switchPlayer() { currentPlayer = (currentPlayer == 'X') ? 'O' : 'X'; } public static void main(String[] args) { Reversi game = new Reversi(); game.printBoard(); // 测试放置game.placePiece(2, 4); game.printBoard(); } } ``` --- #### 关键点解析 1. **棋盘初始化** `initializeBoard` 方法设置了一个标准的 8×8 大小棋盘,并预置了中心四格的初始布局[^2]。 2. **合法性检测** 函数 `isValidMove` 负责确认目标位置是否为空且能够至少在一个方向上形成有效的翻转序列。 3. **翻转机制** 在函数 `flipPieces` 中实现了对符合条件的方向上的所有敌方子进行翻转的操作。 4. **切换玩家控制权** 每次有效行动之后调用 `switchPlayer` 来改变回合归属给另一名选手。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值