基本思想
五子棋存在多种连接方式,这决定了每一个空位的权值有所不同。我们对五子棋的不同连接方式设置权值,然后遍历棋盘,算出每一个空位上的权值,选择权值最大的空位下棋。因此,该算法的关键在于:
- 设置并且存储不同连接方式及其对应的权值。
- 计算棋盘空位上的权值。
设置不同连接方式的权值并进行存储
棋子的连接分为活连与死连。假设0代表空位,1代表黑棋,2代表白棋。例如,010为活连,01(遇到边界)为死连。为不同的连接方式设置对应的权值:
假设0代表空位,1代表黑棋,2代表白棋。
权值表(还可以细分):
- 连接方式:010,权值:50;0110,权值:150;01110,权值:500;011110,权值:3000;
- 连接方式:020,权值:50;0220,权值:150;02220,权值:500;022220,权值:3000;
- 连接方式:01,权值:30;011,权值:90;0111,权值:300;01111,权值:3000;
- 连接方式:02,权值:30;022,权值:90;0222,权值:300;02222,权值:3000。
设置好权值表后,就要考虑如何存储这些权值。因为后续计算空位总权值需要这些数据。这里考虑用哈希表进行存储“连接方式——权值”这样的键值对。
Key-Value:键值对
HashMap:将键值对一起存入,可以通过键来查询对应的值。将连子情况作为Key,权值作为Value。
HashMap 存储优势:查询时是O(1)的时间复杂度。
HashMap 存储原理:用Key来计算一个hash值(当作唯一标识),然后将Key-Value存储在数组中对应下标位置。
操作:
- 实例化:
HashMap<String,Integer> codeMap = new HashMap();
- 方法:
code.put(key,value);
/value = code.get(key);
遍历表格计算权值
以一个五子棋盘为例:

尝试计算a、b两个空位处的权值大小。我们可以发现空位处的连接可以往上、下、左、右、左上、右上、左下、右下八个方向进行搜索。同时规定一个空位的权值由这八个方向的连接带来的权值简单相加得到(规则不唯一)。
对于a:往左的连接为01,权值30;往下的连接为01,权值30;往右下的连接为010,权值50。故a处的权值为30+30+50=110。
对于b:往左的连接为022,权值90;往上的连接为01,权值30;往左上的连接为011,权值90。故b处的权值为90+30+90=210。
有了上面的举例,下面通过遍历计算每一个空位的权值。上面的代码中往八个方向计算权值,但具体方法还未定义。下面以往右和往左上为例进行说明。
往右的搜索方法示例(伪代码):
// 假设当前位置为(x, y)
int rightWeight = 0; // 初始化向右连接的权重为 0
for (int i = 1; i < 5; i++) { // 向右搜索五个位置(五子棋的棋子数)
int nextX = x + i; // 获取当前位置向右移动 i 个位置的 x 坐标
if (nextX < 15) { // 确保不超出棋盘范围(假设棋盘大小为 15x15)
// 根据当前位置的棋子情况计算权重并累加到 rightWeight 中
// ...(具体计算逻辑略)
} else {
break; // 超出棋盘范围时停止搜索
}
}
// 将计算得到的 rightWeight 存储到相应的位置(例如 codeArray[x][y])...(具体存储逻辑略)
往左上的搜索方法示例(伪代码):可以类似地实现。以上无论是往哪个方向计算出来的权值都需要累加到codeArray对应位置(codeArray是已经定义的存储权值的二维数组)。完整代码可以基于上述思路进行实现。