五子棋是全国智力运动会竞技项目之一,容易上手,老少皆宜,而且趣味横生,引人入胜,不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。当然,用 JAVA 语言编写五子棋 AI 小游戏也是一件非常有意思的事:

先上效果图:

一、五子棋规则

五子棋的基本规则如下:
(1) 棋盘:采用国际上标准的 15×15 路线的正方形棋盘。
(2)下法:两人分别执黑白两色棋子,轮流在棋盘上选择一个无子的交叉点走子,无子的交叉点又称为空点,规定由黑方先行走棋。
(3)输赢判断:黑、白双方有一方的五个棋子在衡、竖或斜的方向上联接成无间断的一条线即为该方赢。

二、思路分析

(1)下五子棋首先需要一个棋盘,国际标准是 15×15 路线,为了增加趣味性,我们在编写程序时可以使用不同线路的棋盘。

(2)用户在开始游戏前可进行相关选择,如:模式选择(人人对战、人机对战),颜色选择(用户要黑棋、用户要白棋),下棋顺序(黑棋先行、白棋先行),并且设置有“开始游戏”、“重新开始”、“认输结束”、“悔棋”等按钮。

(3)开始游戏后,用户在棋盘上点击相应的位置就可以下棋子(人人模式黑白子交替出现,人机模式用户在下完一个子后电脑也会自动下一个子),且每下一步棋系统需要判断横竖斜这几个方向上是否有连续相同颜色的五个棋子。

(4)在游戏过程中,当用户改变界面大小和拖动界面,即调用 paint 函数时棋盘和棋子不会消失。

简简单单几个步骤,顿时感觉难度也不高,下面开工!let's go !!!

三、代码详解

首先,我们需要画一个棋盘,new 一个 ImageUI 类(当然也可以取其他名字),在这个类中,我们需要把五子棋的界面画出来,为了方便管理,在 JFrame 上设置了两个 JPanel,一个JPanel 里放 ImagePanel,用于棋盘和棋子的绘制,另一个JPanel 里放相关按钮。

为了能够实现模式选择等单选功能,这边使用了单选按钮 JRadioButton,并打包放入一个 group 中,由于按钮紧挨在一起不美观,我们在部分按钮后面增加了一个空的 JLabel。

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;public class ImageUI extends JFrame implements Config{ImageListener ul = new ImageListener();ImagePanel imgPanel = new ImagePanel();public static void main(String[] args){new ImageUI();}ImageUI(){initUI();}private void initUI(){JFrame jf = frameInitUI();JPanel[] jps = addPanel(jf);addButton(jps,ul);jf.setVisible(true);Graphics gr = imgPanel.getGraphics();ul.g = gr;ul.imgPanel = imgPanel;imgPanel.qz = ul.qz;imgPanel.addMouseListener(ul);}private void addButton(JPanel[] jps, ActionListener al) {JLabel j0 = new JLabel("                        ");jps[1].add(j0);String[] btnstrs = new String[]{"开始游戏","重新开始","认输结束","悔棋一步","  模式  ","人人对战","人机对战","  颜色  ","我要黑棋","我要白棋","  顺序  ","黑棋先行","白棋先行"};for (int i = 0; i < 4; i++){JButton btn = new JButton(btnstrs[i]);Dimension dim = new Dimension(120,40);btn.setPreferredSize(dim);btn.setFont(new Font("黑体",1,20));btn.setBackground(Color.WHITE);btn.addActionListener(ul);jps[1].add(btn);}JLabel j1 = new JLabel("                        ");jps[1].add(j1);JLabel j2 = new JLabel(btnstrs[4]);j2.setFont(new Font("楷体",1,30));jps[1].add(j2);ButtonGroup group1 = new ButtonGroup();for (int i = 5; i < 7; i++){JRadioButton jrb = new JRadioButton(btnstrs[i]);jrb.setPreferredSize(new Dimension(120,40));jrb.setFont(new Font("黑体",1,20));jrb.setSelected(true);jrb.setBackground(Color.YELLOW);jrb.addActionListener(ul);group1.add(jrb);jps[1].add(jrb);}JLabel j3 = new JLabel("                        ");jps[1].add(j3);JLabel j4 = new JLabel(btnstrs[7]);j4.setFont(new Font("楷体",1,30));jps[1].add(j4);ButtonGroup group2 = new ButtonGroup();for (int i = 8; i < 10; i++){JRadioButton jrb = new JRadioButton(btnstrs[i]);jrb.setPreferredSize(new Dimension(120,40));jrb.setFont(new Font("黑体",1,20));jrb.setSelected(true);jrb.setBackground(Color.YELLOW);jrb.addActionListener(ul);group2.add(jrb);jps[1].add(jrb);}JLabel j5 = new JLabel("                        ");jps[1].add(j5);JLabel j6 = new JLabel(btnstrs[10]);j6.setFont(new Font("楷体",1,30));jps[1].add(j6);ButtonGroup group3 = new ButtonGroup();for (int i = 11; i < 13; i++){JRadioButton jrb = new JRadioButton(btnstrs[i]);jrb.setPreferredSize(new Dimension(120,40));jrb.setFont(new Font("黑体",1,20));jrb.setSelected(true);jrb.setBackground(Color.YELLOW);jrb.addActionListener(ul);group3.add(jrb);jps[1].add(jrb);}}private JPanel[] addPanel(JFrame jf) {JPanel[] jps = new JPanel[2];String[] layoustrs = {BorderLayout.CENTER,BorderLayout.EAST};imgPanel.setBackground(Color.LIGHT_GRAY);jf.add(imgPanel,layoustrs[0]);jps[0] = imgPanel;Dimension dim = new Dimension(200,0);JPanel jp_s = new JPanel();jp_s.setBackground(Color.ORANGE);jp_s.setPreferredSize(dim);jf.add(jp_s,layoustrs[1]);jps[1] = jp_s;return jps;}private JFrame frameInitUI() {setTitle("五子棋AI");setSize(X0+SIZE*LINE+200,Y0+SIZE*LINE+SIZE);setLocationRelativeTo(null);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);return this;}}

界面画好后,我们需要考虑下棋了,new 一个 ImageListener 类:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;public class ImageListener extends Listen implements Config{public Graphics g = null;private int count = 0;  //偶数黑棋 奇数白棋private int index = 0;  //0无棋 1黑棋 2白棋private int m,n;        //第m行 第n列private String name = null;private String option = null;public int[][] qz = new int[LINE][LINE];public int[][] score = new int[LINE][LINE];public int[] cc = new int[4];public int goalX = 0;public int goalY = 0;public int mark = 0;public int p = 1;Boolean moshi = true;Boolean yanse = true;Boolean shunxu = true;Boolean renji = true;Boolean same = true;ImagePanel imgPanel = new ImagePanel();Login lo = new Login();@Overridepublic void actionPerformed(ActionEvent e){System.out.println("按钮被调用");name = e.getActionCommand();if("人人对战".equals(name)) moshi = true;if("人机对战".equals(name)) moshi = false;if("我要黑棋".equals(name)) yanse = true;if("我要白棋".equals(name)) yanse = false;if("黑棋先行".equals(name)) shunxu = true;if("白棋先行".equals(name)) shunxu = false;if (moshi && shunxu) {count = 2;}if (moshi && !shunxu) {count = 1;}if(!moshi && yanse && shunxu){  //人先出黑count = 2;}if(!moshi && yanse && !shunxu){  //机先出白count = 2;}if(!moshi && !yanse && shunxu){  //机先出黑count = 1;}if(!moshi && !yanse && !shunxu){  //人先出白count = 1;}if("认输结束".equals(name)){option = "认输结束";lo.showU(option);}if("悔棋一步".equals(name)){cancel(qz);}if("开始游戏".equals(name)){same = true;for(int i = 0; i < 4; i++){cc[i] = 0;}for(int i = 0; i < LINE; i++){for(int j = 0; j < LINE; j++){qz[i][j] = 0;}}if(!moshi && yanse && !shunxu) {cc[2] = LINE/2;cc[3] = LINE/2;qz[LINE/2][LINE/2] = 2;}if(!moshi && !yanse && shunxu) {cc[2] = LINE/2;cc[3] = LINE/2;qz[LINE/2][LINE/2] = 1;}imgPanel.paint(g);option = "开始游戏";lo.showU(option);System.out.println("我去调用他");}if("重新开始".equals(name)){same = true;for(int i = 0; i < LINE; i++){for(int j = 0; j < LINE; j++){qz[i][j] = 0;}}imgPanel.paint(g);}}@Overridepublic void mousePressed(MouseEvent e){if(renji) {cc[0] = cc[2];cc[1] = cc[3];}}@Overridepublic void mouseReleased(MouseEvent e){System.out.println("释放被调用");if(renji) {int x = e.getX();int y = e.getY();if (count % 2 == 0) {index = 1;}if (count % 2 == 1) {index = 2;}if ((x > (X0 - SIZE / 2)) && (x < (X0 - SIZE / 2 + SIZE * LINE)) &&(y > (Y0 - SIZE / 2)) && (y < (Y0 - SIZE / 2 + SIZE * LINE))) {m = (x - X0 + SIZE / 2) / SIZE;n = (y - Y0 + SIZE / 2) / SIZE;if (qz[m][n] == 0) {cc[2] = m;cc[3] = n;qz[m][n] = index;count++;imgPanel.drawqz(qz, g);judge(qz);System.out.println("判断被调用");same = true;} else {option = "同一位置";lo.showU(option);same = false;}System.out.println("m=" + m + ";n=" + n);}try {Thread.sleep(500);} catch (InterruptedException ex) {ex.printStackTrace();}if (same && p < 5) {if (!moshi) {renji = false;AI(qz);if (yanse) qz[goalX][goalY] = 2;if (!yanse) qz[goalX][goalY] = 1;imgPanel.drawqz(qz, g);count++;cc[0] = cc[2];cc[1] = cc[3];cc[2] = goalX;cc[3] = goalY;judge(qz);}}}}private void judge(int[][] qz){//判断|情形for(int i = 0; i < LINE; i++){for(int j = 0; j < LINE-1; j++){if(qz[i][j] == qz[i][j+1] && qz[i][j] != 0){p++;if(p > 4 && qz[i][j] == 1) {option = "黑棋胜";lo.showU(option);
//                        same = false;return;}if(p > 4 && qz[i][j] == 2) {option = "白棋胜";lo.showU(option);
//                        same = false;return;}}if(qz[i][j] != qz[i][j+1]){p = 1;}}}//判断——情形for(int j = 0; j < LINE; j++){for(int i = 0; i < LINE-1; i++){if(qz[i][j] == qz[i+1][j] && qz[i][j] != 0){p++;if(p > 4 && qz[i][j] == 1) {option = "黑棋胜";lo.showU(option);
//                        same = false;}if(p > 4 && qz[i][j] == 2) {option = "白棋胜";lo.showU(option);
//                        same = false;return;}}if(qz[i][j] != qz[i+1][j]){p = 1;}}}//判断\情形for(int i = 0; i < LINE-4; i++){for(int j = 0; j < LINE-4; j++){int m = i;int n = j;for(int cishu = 0; cishu < 5; cishu++) {if (qz[m][n] == qz[m + 1][n + 1] && qz[m][n] != 0) {p++;m++;n++;if (p > 4 && qz[m][n] == 1) {System.out.println("调用黑棋胜1");option = "黑棋胜";lo.showU(option);
//                            same = false;return;}if (p > 4 && qz[m][n] == 2) {System.out.println("调用白棋胜1");option = "白棋胜";lo.showU(option);
//                            same = false;return;}}if (qz[m][n] != qz[m + 1][n + 1]) {p = 1;}}}}//判断/情形for(int i = 4; i < LINE; i++){for(int j = 0; j < LINE-4; j++){int m = i;int n = j;for(int cishu = 0; cishu < 5; cishu++) {if (qz[m][n] == qz[m - 1][n + 1] && qz[m][n] != 0) {p++;m--;n++;if (p > 4 && qz[m][n] == 1) {System.out.println("调用黑棋胜2");option = "黑棋胜";lo.showU(option);
//                            same = false;return;}if (p > 4 && qz[m][n] == 2) {System.out.println("调用白棋胜2");option = "白棋胜";lo.showU(option);
//                            same = false;return;}}if (qz[m][n] != qz[m - 1][n + 1]) {p = 1;}}}}}private void cancel(int[][] qz){qz[cc[0]][cc[1]] = 0;qz[cc[2]][cc[3]] = 0;imgPanel.paint(g);}private void AI(int[][] qz){for(int i = 0; i  < LINE; i++){for(int j = 0; j < LINE; j++){score[i][j] = 0;}}int blackChessNum = 0;int whiteChessNum = 0;//扫描|for(int i = 0; i < LINE; i++){System.out.println("|被扫描了");for(int j = 0; j < LINE-4; j++){int k = j;while(k < j + 5){if(qz[i][k] == 1) blackChessNum++;if(qz[i][k] == 2) whiteChessNum++;k++;}mark = weight(blackChessNum, whiteChessNum);for(k = j; k < j + 5; k++){if(qz[i][k] == 0) score[i][k] += mark;}blackChessNum = 0;whiteChessNum = 0;mark = 0;}}//扫描——for(int j = 0; j < LINE; j++){System.out.println("——被扫描了");for(int i = 0; i < LINE-4; i++){int k = i;while(k < i + 5){if(qz[k][j] == 1) blackChessNum++;if(qz[k][j] == 2) whiteChessNum++;k++;}mark = weight(blackChessNum, whiteChessNum);for(k = i; k < i + 5; k++){if(qz[k][j] == 0) score[k][j] += mark;}blackChessNum = 0;whiteChessNum = 0;mark = 0;}}//扫描\for(int i = 0; i < LINE-4; i++){System.out.println("\\被扫描了");for(int j = 0; j < LINE-4; j++){int k = 0;while(k < 5){if(qz[i+k][j+k] == 1) blackChessNum++;if(qz[i+k][j+k] == 2) whiteChessNum++;k++;}mark = weight(blackChessNum, whiteChessNum);for(k = 0; k < 5; k++){if(qz[i+k][j+k] == 0) score[i+k][j+k] += mark;}blackChessNum = 0;whiteChessNum = 0;mark = 0;}}//扫描/for(int i = 4; i < LINE; i++){System.out.println("/被扫描了");for(int j = 0; j < LINE-4; j++){int k = 0;while(k < 5){if(qz[i-k][j+k] == 1) blackChessNum++;if(qz[i-k][j+k] == 2) whiteChessNum++;k++;}mark = weight(blackChessNum, whiteChessNum);for(k = 0; k < 5; k++){if(qz[i-k][j+k] == 0) score[i-k][j+k] += mark;}blackChessNum = 0;whiteChessNum = 0;mark = 0;}}//从空位置中找到得分最大的位置int scoremax = 0;for(int j = 0; j < LINE; j++){System.out.println("");for(int i = 0; i < LINE; i++){System.out.print(score[i][j]+";");if(scoremax < score[i][j]){scoremax = score[i][j];goalX = i;goalY = j;}}}renji = true;}private int weight(int blackChessNum,int whiteChessNum) {System.out.println("blackChessNum="+blackChessNum+";whiteChessNum="+whiteChessNum);if(blackChessNum > 0 && whiteChessNum > 0) mark = 0;if(blackChessNum == 0 && whiteChessNum == 0) mark = 7;if(blackChessNum == 1 && whiteChessNum == 0 && yanse) mark = 15;if(blackChessNum == 1 && whiteChessNum == 0 && !yanse) mark = 35;if(whiteChessNum == 1 && blackChessNum == 0 && yanse) mark = 35;if(whiteChessNum == 1 && blackChessNum == 0 && !yanse) mark = 15;if(blackChessNum == 2 && whiteChessNum == 0 && yanse) mark = 400;if(blackChessNum == 2 && whiteChessNum == 0 && !yanse) mark = 800;if(whiteChessNum == 2 && blackChessNum == 0 && yanse) mark = 800;if(whiteChessNum == 2 && blackChessNum == 0 && !yanse) mark = 400;if(blackChessNum == 3 && whiteChessNum == 0 && yanse) mark = 1800;if(blackChessNum == 3 && whiteChessNum == 0 && !yanse) mark = 15000;if(whiteChessNum == 3 && blackChessNum == 0 && yanse) mark = 15000;if(whiteChessNum == 3 && blackChessNum == 0 && !yanse) mark = 1800;if(blackChessNum == 4 && whiteChessNum == 0 && yanse) mark = 100000;if(blackChessNum == 4 && whiteChessNum == 0 && !yanse) mark = 800000;if(whiteChessNum == 4 && blackChessNum == 0 && yanse) mark = 800000;if(whiteChessNum == 4 && blackChessNum == 0 && !yanse) mark = 100000;return mark;}}

ImageListener 类是五子棋 AI 代码的核心部分,下面从模式选择,胜负判断,悔棋三方面进行简要分析:

模式判断:

在人人对战中,我们用 count 计数,偶数下黑子,奇数下白子,为了实现下的第一颗棋子是黑子还是白子,可对应给 count 的初值赋 1 或 2,每下完一步棋进行胜负判断;

在人机对战模式中,主要难点是电脑自主判断落子位置,本篇文章采用了已经公开的五元组评分算法,即对15X15的572个五元组分别评分,一个五元组的得分就是该五元组为其中每个位置贡献的分数,一个位置的分数就是其所在所有五元组分数之和,所有空位置中分数最高的那个位置就是落子位置。

五子棋 AI 算法其实还有很多,这边再介绍一种也较广泛使用的算法,即根据特征来赋评估分值,同一特征可能在不同路上(甚至同一路上)会重复出现,一些威胁性小的特征即使出现多次,累加得分也不应该超过一个极有威胁性的特征得分。如特征“++OO++”威胁性小,特征“+OOOO+”威胁性非常大,不管前者出现多少个,原则上得分都不应该超过后者出现一个的得分,在此提供一个已有的特征评分表供参考:

胜负判断

在游戏过程中,我们初始化了一个和棋盘线数一样的二维数组,用于记录每一个交点的落子情况,我们规定:若该交点处没有棋子,则数组相应位置元素为0;若该交点处有一颗黑子,则数组相应位置为1;若该交点处有一颗白子,则数组相应位置为2;每下完一颗棋子,都会调用 judge 函数对该二维数组进行横向,竖向,左斜向,右斜向扫描,判断是否有连续五个1或者五个2.

悔棋

我们定义了一个长度为4的一维数组,分别记录倒数第二颗棋子的 x,y 坐标和最后一颗棋子的 x, y 坐标,当点击“悔棋一步”按钮时,把这两个棋子对应二维数组中的值置为0,并调用 paint 函数,则在重绘时这两颗棋子将不会绘制出来,即实现了悔棋功能!

当界面发生改变时,会调用 paint 函数,因此我们还写了一个 ImagePanel 类,里面重写了 paint 函数。

import javax.swing.*;
import java.awt.*;public class ImagePanel extends JPanel implements Config{public int[][] qz = new int[LINE][LINE];public void paint(Graphics gr){super.paint(gr);drawChessTable(gr);drawqz(qz,gr);}public void drawqz(int[][] qz,Graphics gr) {System.out.println("棋子重绘");for(int i = 0; i < LINE; i++){for(int j = 0; j < LINE; j++){if(qz[i][j] == 1){System.out.println("qz["+i+"]["+j+"]="+qz[i][j]);gr.setColor(Color.BLACK);gr.fillOval(X0+i*SIZE-CHESS/2, Y0+j*SIZE-CHESS/2, CHESS, CHESS);}if(qz[i][j] == 2){System.out.println("qz["+i+"]["+j+"]="+qz[i][j]);gr.setColor(Color.WHITE);gr.fillOval(X0+i*SIZE-CHESS/2, Y0+j*SIZE-CHESS/2, CHESS, CHESS);}}}}private void drawChessTable(Graphics gr) {Graphics2D gr2 = (Graphics2D)gr;gr2.setStroke(new BasicStroke(2.0f));for(int i = 0; i < LINE; i++){gr2.drawLine(X0,SIZE*i+Y0,X0+SIZE*(LINE-1),SIZE*i+Y0);}for(int j = 0; j < LINE; j++){gr2.drawLine(X0+SIZE*j,Y0,X0+SIZE*j,Y0+SIZE*(LINE-1));}}}

最后,为了能使这个代码能够顺利运行,还需要加上以下几个类:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;public class Listen implements MouseListener, ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {}@Overridepublic void mouseClicked(MouseEvent e) {}@Overridepublic void mousePressed(MouseEvent e) {}@Overridepublic void mouseReleased(MouseEvent e) {}@Overridepublic void mouseEntered(MouseEvent e) {}@Overridepublic void mouseExited(MouseEvent e) {}
}
public interface Config {public static final int X0 = 50;public static final int Y0 = 50;public static final int SIZE = 50;public static final int LINE = 15;public static final int CHESS = 50;
}
public class Login {public void showU(String option){JFrame jf = new JFrame();jf.setSize(500,300);switch (option){case"黑棋胜":ImageIcon image1 = new ImageIcon("D:\\03.jpg");JLabel jl1 = new JLabel(image1);jf.add(jl1);jf.setTitle("黑棋胜");jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);break;case"白棋胜":ImageIcon image2 = new ImageIcon("D:\\04.jpg");JLabel jl2 = new JLabel(image2);jf.add(jl2);jf.setTitle("白棋胜");jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);break;case"开始游戏":ImageIcon image3 = new ImageIcon("D:\\01.jpg");JLabel jl3 = new JLabel(image3);jf.add(jl3);jf.setTitle("开始游戏");jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);break;case"认输结束":ImageIcon image4 = new ImageIcon("D:\\02.jpg");JLabel jl4 = new JLabel(image4);jf.add(jl4);jf.setTitle("认输结束");jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);break;case"同一位置":ImageIcon image5 = new ImageIcon("D:\\05.jpg");JLabel jl5 = new JLabel(image5);jf.add(jl5);jf.setTitle("无效棋");jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);break;}jf.setLocationRelativeTo(null);jf.setVisible(true);}
}

在最后,献上代码中使用到的五张图片:

01:

02:

03:

04:

05:

JAVA五子棋AI(人机对战 颜色选择 悔棋等 可直接使用)相关推荐

  1. Android 蓝牙五子棋[可人机对战]——完整篇

    前言 我之前做了个人机对战的五子棋, AI算法很垃圾, 然后各种逻辑很糟糕, 已经很久没有维护了, 今天看了篇文章, 是用了蓝牙和Wifi的五子棋对战, 我觉得很有意思, 毕竟自己没做过蓝牙连接这方面 ...

  2. Java 五子棋AI博弈树算法实现

    实际上现在的棋类AI都是采用了效率更高的算法(如蒙特卡洛树搜索)+Deep Learning实现.今天我们只探讨较简单的五子棋AI,大致有两种算法:五元组和博弈树. Java学习笔记 第一节 Java ...

  3. python五子棋人机对战_Python:游戏:五子棋之人机对战

    原标题:Python:游戏:五子棋之人机对战 开端 画棋盘 首先肯定是要画出棋盘来,用 pygame 画出一个 19 × 19 或 15 × 15 的棋盘并不是什么难事,这在之前的文章中已经多次用到, ...

  4. 步步为营-墙棋AI人机对战(Android)

    放纵了三天了,之前写了一半懒得去动的墙棋,反而在这几天间隙断断续续完成了,也是挺可笑的. 简介-关于墙棋 路墙棋(Quoridor),或译墙棋.步步为营,是由Mirko Marchesi(米尔科·迈凯 ...

  5. java五子棋AI算法人机对战(春物彩羽版可下载试玩PC端)

    五子棋AI算法 前言: 坐标西安,写于疫情封城期间.改进了之前写的基于极大极小值策略AI五子棋游戏,是用java实现的,采用了java老旧的jframe窗体和绘图类.写好之后整理成了这篇博客. 游戏采 ...

  6. java人际对战五子棋_系统框图如下 java实现五子棋程序 可以实现人人对战 人机对战 简单功能 悔棋 认输...

    展开全部 一.实验题目 五子棋游戏e69da5e6ba9062616964757a686964616f31333365633835. 二.问题分析 五子棋是双人博弈棋类益智游戏,由围棋演变而来,属纯策 ...

  7. Python实现五子棋:人机对战 / 人人对战(动图演示)

    前言 过完520,咱们来玩玩五子棋陶冶情操.快拿这个和你女朋友去对线.(分了别来找我哇).多的不说直接进入正题 人人对战 游戏规则:p1为黑子,p2为白子,黑子先手,一方达到五子相连即为获胜. 动态演 ...

  8. Bombermaaan-最好的开源炸弹人游戏(支持AI人机对战,SFC复刻版)

    关键词:炸弹人源代码,炸弹人AI算法 目录 一.游戏截图 二.基本信息 三.游戏设计介绍 四.道具说明 五.下载 一.游戏截图       二.基本信息 语言:C++ 平台:Windows / Lin ...

  9. Java小程序——简单五子棋(人机对战)

    有关五子棋人人对战的代码,以及其他一些我想说的话请参考 Java小程序 -- 简单五子棋_如切如磋,如琢如磨-CSDN博客_java小程序 由于某些原因,这里我给出的AI算法算是比较简单的,所以导致了 ...

最新文章

  1. css3-transform
  2. thinkphp分页格式的完全自定义,直接输入数字go到输入数字页
  3. html三张图片的轮播代码_vue写了个轮播图
  4. php sub pos,PHP pos()用法及代码示例
  5. 试试用word发博客
  6. hash冲突(碰撞)及解决方法
  7. 分布式网络爬虫功能模块组成
  8. 北大 CTSC 2013
  9. NSUOJ2888最小唯一表示前缀(偷懒的xzj)
  10. 「网络安全」安全设备篇(8)——流量监控
  11. 《学Unity的猫》——第十章:Unity的物理碰撞,流浪喵星计划
  12. oracle failover mode,Oracle RAC FailOver配置
  13. @RequestBody、 @RequestParam 、 @PathVariable 和 @Vaild 注解的使用及区别
  14. Python中常见的__init__.py是什么意思?详解Python import的方式和原理
  15. 权威的计算机类期刊,计算机类期刊权威排名
  16. 通过一个网络错误简述DNS
  17. oracle保留六位小数,oracle 小数保留位数
  18. Java解压缩技术(三)BZIP2压缩-解压缩
  19. Mongodb 学习笔记简介
  20. DICOM-RT struct使用python脚本转换为nii.gz

热门文章

  1. python五子棋单机版源代码_Python基于pygame实现单机版五子棋对战
  2. 晋中学院计算机信息与技术学院,晋中学院
  3. 1分钟链圈 | 快播创始人王欣成立区块链公司,获3000万美元融资
  4. 【QQ空间】免费flash挂件
  5. 浙大版《C语言程序设计实验与习题指导(第4版)》题目集-编程题-实验2-2-6 3人分糖果 (5分)
  6. Java获取去年同月份相同星期的日期算法
  7. Chrome 浏览器以 58.09% 的市场占有率稳居世界第一
  8. 嵌入式Linux驱动学习之路(二十六)DM9000C网卡驱动程序
  9. 关于常成员函数对非常成员函数的调用问题
  10. 深入了解Flutter的isolate(4) --- 使用Compute写isolate