- 浏览: 1205 次
- 性别:
- 来自: 杭州
文章分类
最新评论
这款五子棋小游戏是我五六年前在培训的时候花了一整个下午时间即兴写出来的,功能很简单,实现了五子棋的电脑对战,主要就是为了研究下电脑下棋算法,所以其他的功能和细节都没考虑,比如电脑最后的落子点我是直接用图片标示出来的,最好是另建一个线程来闪烁最后落子点,还有智能等级也是可以调节的,偏重于防守和进攻都可以修改代码中权值的设定来实现的,有兴趣的朋友可以在此基础上扩展一下。因为没有写谁先下棋的功能,可以模拟下电脑先下子,只需要你在边角上先下一子就可以了,相比下来,电脑先下的话,电脑赢的几率更大点,一共用到了三张图片,都在附件中。
下面是全部的代码,写了一些注释,希望能对你阅读代码起到一点帮助
import java.awt.*; import java.awt.event.*; import java.net.URL; import javax.swing.*; public class GobangGame { public static void main(String[] args) { GameF game = new GameF(); game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); game.show(); } } class GameF extends JFrame { public GameF() { Container contentPane = getContentPane(); final Panel panel = new Panel(); panel.setBackground(new Color(255, 182, 147)); contentPane.setBackground(new Color(255, 182, 147)); contentPane.add(panel); setSize(560, 560); setTitle("杨雷的五子棋游戏 版本1.0"); setResizable(false); panel.setCursor(new Cursor(Cursor.HAND_CURSOR)); JMenuBar menuBar=new JMenuBar(); JMenu menu=new JMenu("选项"); JMenuItem menuStart=new JMenuItem("开始游戏"); menuStart.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ panel.ResetGame(); panel.repaint(); } }); JMenuItem menuExit =new JMenuItem("退出"); menuExit.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ System.exit(0); } }); menuBar.add(menu); menu.add(menuStart); menu.add(menuExit); this.setJMenuBar(menuBar); } } class Panel extends JPanel { private URL blackImgURL = GobangGame.class.getResource("black.gif"); private ImageIcon black=new ImageIcon(blackImgURL); private URL whiteImgURL = GobangGame.class.getResource("white.gif"); private ImageIcon white=new ImageIcon(whiteImgURL); private URL currentImgURL = GobangGame.class.getResource("current.gif"); private ImageIcon current=new ImageIcon(currentImgURL); private int i, j, k, m, n, icount; private int[][] board = new int [16][16]; private boolean[][][] ptable = new boolean[16][16][672]; private boolean[][][] ctable = new boolean[16][16][672]; private int[][] cgrades = new int[16][16]; private int[][] pgrades = new int[16][16]; private int cgrade,pgrade; private int[][] win = new int[2][672]; private int oldx,oldy; private int bout=1; private int pcount,ccount; private boolean player,computer,over,pwin,cwin,tie,start; private int mat,nat,mde,nde; public Panel(){ addMouseListener(new Xiazi()); this.ResetGame(); } public void paintComponent(Graphics g) { super.paintComponent(g); for (int i = 0; i < 16; i++) for (int j = 0; j < 16; j++){ g.drawLine(50, 50 + j * 30, 500, 50 + j * 30); } for (int i = 0; i < 16; i++) for (int j = 0; j < 16; j++){ g.drawLine(50 + j * 30, 50, 50 + j * 30, 500); } for (int i = 0; i < 16; i++){ String number = Integer.toString(i); g.drawString(number, 46 + 30 * i, 45); } for (int i = 1; i < 16; i++){ String number = Integer.toString(i); g.drawString(number, 33, 53 + 30 * i); } updatePaint(g); } class Xiazi extends MouseAdapter{ public void mouseClicked(MouseEvent e){ if(!over) { oldx = e.getX(); oldy = e.getY(); mouseClick(); repaint(); } } } // 游戏初始化 public void ResetGame() { //初始化棋盘 for(i=0;i<16;i++) for(j=0;j<16;j++) { this.pgrades[i][j] = 0; this.cgrades[i][j] = 0; this.board[i][j] = 2; } //遍历所有的五连子可能情况的权值 //横 for(i=0;i<16;i++) for(j=0;j<12;j++){ for(k=0;k<5;k++){ this.ptable[j+k][i][icount] = true; this.ctable[j+k][i][icount] = true; } icount++; } //竖 for(i=0;i<16;i++) for(j=0;j<12;j++){ for(k=0;k<5;k++){ this.ptable[i][j+k][icount] = true; this.ctable[i][j+k][icount] = true; } icount++; } //右斜 for(i=0;i<12;i++) for(j=0;j<12;j++){ for(k=0;k<5;k++){ this.ptable[j+k][i+k][icount] = true; this.ctable[j+k][i+k][icount] = true; } icount++; } //左斜 for(i=0;i<12;i++) for(j=15;j>=4;j--){ for(k=0;k<5;k++){ this.ptable[j-k][i+k][icount] = true; this.ctable[j-k][i+k][icount] = true; } icount++; } for(i=0;i<=1;i++) //初始化黑子白子上的每个权值上的连子数 for(j=0;j<672;j++) this.win[i][j] = 0; this.player = true; this.icount = 0; this.ccount = 0; this.pcount = 0; this.start = true; this.over = false; this.pwin = false; this.cwin = false; this.tie = false; this.bout=1; } public void ComTurn(){ //找出电脑(白子)最佳落子点 for(i=0;i<=15;i++) //遍历棋盘上的所有坐标 for(j=0;j<=15;j++){ this.pgrades[i][j]=0; //该坐标的黑子奖励积分清零 if(this.board[i][j] == 2) //在还没下棋子的地方遍历 for(k=0;k<672;k++) //遍历该棋盘可落子点上的黑子所有权值的连子情况,并给该落子点加上相应奖励分 if(this.ptable[i][j][k]){ switch(this.win[0][k]){ case 1: //一连子 this.pgrades[i][j]+=5; break; case 2: //两连子 this.pgrades[i][j]+=50; break; case 3: //三连子 this.pgrades[i][j]+=180; break; case 4: //四连子 this.pgrades[i][j]+=400; break; } } this.cgrades[i][j]=0;//该坐标的白子的奖励积分清零 if(this.board[i][j] == 2) //在还没下棋子的地方遍历 for(k=0;k<672;k++) //遍历该棋盘可落子点上的白子所有权值的连子情况,并给该落子点加上相应奖励分 if(this.ctable[i][j][k]){ switch(this.win[1][k]){ case 1: //一连子 this.cgrades[i][j]+=5; break; case 2: //两连子 this.cgrades[i][j]+=52; break; case 3: //三连子 this.cgrades[i][j]+=100; break; case 4: //四连子 this.cgrades[i][j]+=400; break; } } } if(this.start){ //开始时白子落子坐标 if(this.board[4][4]==2){ m = 4; n = 4; }else{ m = 5; n = 5; } this.start = false; }else{ for(i=0;i<16;i++) for(j=0;j<16;j++) if(this.board[i][j] == 2){ //找出棋盘上可落子点的黑子白子的各自最大权值,找出各自的最佳落子点 if(this.cgrades[i][j]>=this.cgrade){ this.cgrade = this.cgrades[i][j]; this.mat = i; this.nat = j; } if(this.pgrades[i][j]>=this.pgrade){ this.pgrade = this.pgrades[i][j]; this.mde = i; this.nde = j; } } if(this.cgrade>=this.pgrade){ //如果白子的最佳落子点的权值比黑子的最佳落子点权值大,则电脑的最佳落子点为白子的最佳落子点,否则相反 m = mat; n = nat; }else{ m = mde; n = nde; } } this.cgrade = 0; this.pgrade = 0; this.board[m][n] = 1; //电脑下子位置 ccount++; if((ccount == 50) && (pcount == 50)) //平局判断 { this.tie = true; this.over = true; } for(i=0;i<672;i++){ if(this.ctable[m][n][i] && this.win[1][i] != 7) this.win[1][i]++; //给白子的所有五连子可能的加载当前连子数 if(this.ptable[m][n][i]){ this.ptable[m][n][i] = false; this.win[0][i]=7; } } this.player = true; //该人落子 this.computer = false; //电脑落子结束 } public void mouseClick(){ if(!this.over) if(this.player){ if(this.oldx<520 && this.oldy<520) { int m1=m,n1=n; m = (oldx-33)/30; n = (oldy-33)/30; if(this.board[m][n] == 2){ this.bout++; this.board[m][n] = 0; pcount++; if((ccount == 50) && (pcount == 50)){ this.tie = true; this.over = true; } for(i=0;i<672;i++){ if(this.ptable[m][n][i] && this.win[0][i] != 7) this.win[0][i]++; //给黑子的所有五连子可能的加载当前连子数 if(this.ctable[m][n][i]){ this.ctable[m][n][i] = false; this.win[1][i]=7; } } this.player = false; this.computer = true; }else{ m=m1;n=n1; } } } } public void updatePaint(Graphics g){ if(!this.over){ //如果是轮到电脑下 if(this.computer) this.ComTurn(); //得到最佳下子点 //遍历当前棋盘上的五连子情况,判断输赢 for(i=0;i<=1;i++) for(j=0;j<672;j++){ if(this.win[i][j] == 5) if(i==0){ //人赢 this.pwin = true; this.over = true; //游戏结束 break; }else{ this.cwin = true; //电脑赢 this.over = true; break; } if(this.over) //一遇到五连子退出棋盘遍历 break; } g.setFont(new Font("华文行楷",0,20)); g.setColor(Color.RED); //画出当前棋盘所有棋子 for(i=0;i<=15;i++) for(j=0;j<=15;j++){ //如果board元素值为0,则该坐标处为黑子 if(this.board[i][j] == 0){ g.drawImage(black.getImage(),i*30+31,j*30+31,black.getImage().getWidth(black.getImageObserver())-3,black.getImage().getHeight(black.getImageObserver())-3, black.getImageObserver()); } //如果board元素值为1,则该坐标处为白子 if(this.board[i][j] == 1){ g.drawImage(white.getImage(),i*30+31,j*30+31,white.getImage().getWidth(white.getImageObserver())-3,white.getImage().getHeight(white.getImageObserver())-3, white.getImageObserver()); } } //画出白子(电脑)当前所下子,便于辨认 if(this.board[m][n]!=2) g.drawImage(current.getImage(),m*30+31,n*30+31,current.getImage().getWidth(current.getImageObserver())-4,current.getImage().getHeight(current.getImageObserver())-4, current.getImageObserver()); //判断输赢情况 //人赢 if(this.pwin) g.drawString("您太厉害了!再来一次请重新开始游戏..",20,200); //电脑赢 if(this.cwin) g.drawString("很遗憾,你输了!再来一次请重新开始游戏..",84,190); //平局 if(this.tie) g.drawString("不分胜负!再来一次请重新开始游戏..",80,200); g.dispose(); } } }
如果有兴趣的朋友可以和我一起交流下技术, 我QQ号码: 249930610, MSN: yangsharp@hotmail.com
相关推荐
五子棋 matlab 人机对战 较智能系统,适合初学者,易理解。
#最后决定就写个五子棋人机对战吧! #这个源码我在多年前曾用VB6写过,当时毕业设计拿了优秀,之后经过了几次修改计算机Ai还不算太差,想投机赢是没机会的。 #由于本人初学Python(第一个完整的Python程序),有些技巧...
JAVA 五子棋 人机对战 一些简单的人工智能,分析各个位置下棋的权值来判断最佳位置。
五子棋,人机对战,源码,含智能算法,VC++通过编译
turboC2.0通过,人机智能对战,因水平有限,不足之处敬请指导!有详细的注释
简介基于C++的智能五子棋程序,可以实现人机对战、双人对战等 配置环境 Windows 10系统 Visual Studio C++ 11 基于C++的五子棋程序 简介基于C++的智能五子棋程序,可以实现人机对战、双人对战等 配置...
人机对战五子棋游戏代码,棋力可对付一般玩家 学习C# .NET GDI+ 解压密码:130707031
用c#编写的五子棋人机对战 核心算法 核心算法就是计算计算机应该在哪里落子。 思路的伪代码如下。 PC_Stone For i = 1 to 15 For j = 1 to 15 If ( board[i][j] != -1) Qz[i][j] = - Esle FindQz...
这是一个简单的五子棋游戏,可以实现人机对战,选择谁先下,谁后下.代码有不错的界面,可以实现基本的功能
人机对战 主程序框架 人工智能部分缺少 仅供参考
用QT写的五子棋游戏,一年多前在windows SDK里写的,现在移植到Ubuntu下,用于人机对战,实现了三种不同的算法,还可以算法之间对战。 开发环境: ubuntu10.04 linux3.04 gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3 Qt ...
基于MFC编写的智能五子棋,界面简洁友好,规则包含禁手,启动后默认双人本机游戏,可人机对战,可双人联网进行游戏,双人本机游戏和人机对战可直接悔棋,双人联网游戏需要对方同意才能悔棋。 压缩包含源代码和可执行...
在本资源中,我们将探讨如何使用Python编程语言实现一个简单的五子棋人机对战游戏。该项目不仅能够帮助初学者理解基本的游戏开发流程,还能够提供一个平台,让玩家练习并提升自己的五子棋策略。 首先,我们会介绍...
C#做的人机对战五子棋,动态库,含源码,对您学人工智能及C#会有帮助的。
基于C++开发的客户端和服务端组成五子棋联机对战和人机对战系统源码(课程设计).zip 一个五子棋系统 由客户端和服务端组成 可进行联机对战和人机对战一个五子棋系统 由客户端和服务端组成 可进行联机对战和人机对战 ...
完全用C语言实现的五子棋。没有用图形界面,因为不大会…… 但在控制台界面里还算是可以的吧 使计算机具有了一定的人工智能 代码在TXT文本里,复制粘贴就好
五子棋源码,有人机对弈,修改了一下别人的源代码,VS2008编译通过
五子棋的画图下棋以及判断胜负和人工智能 源代码
是一个用vc做的五子棋程序,加入了人工智能,还有对棋局的保存和观看的功能,如果有谁要源代码的给我发E-mail: hzfxjun@hzcnc.com QQ:7097928 欢迎交流 注明五子棋