java 城市四子棋棋程序,求救

 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
四子棋的java实现源代码
下载积分:800
内容提示:四子棋的java实现源代码
文档格式:DOCX|
浏览次数:44|
上传日期: 20:13:10|
文档星级:
该用户还上传了这些文档
四子棋的java实现源代码
官方公共微信Java(25)
& & & &《Java基本功练习九》讲到了五子棋,并且提出了改进的建议。相信大家都掌握了多维数组的相关操作,上一篇提到了检测输赢方法有两种:1)每下一颗棋子就遍历棋盘;2)每下一颗棋子,判断其周围的情况来确定输赢。
& & & & 本篇博文就以悬挂的四子棋作为例子,来讲述2)中的判定方法,由于只需判定当前所下棋子的情况,而不用遍历棋盘,所以效率更高。
& & & & 悬挂的四子棋,又叫连接四子,相信大家小时候都玩过把。它是一个两个人玩的棋盘游戏,在游戏中,玩家轮流将有颜色的棋子放在一个六行七列的垂直悬挂的网格中,如下所示:
& & & & 这个游戏的目的是在反方出现一行、一列或者一对角线上有四个相同颜色的棋子之前,正方能先做到。程序提示两个玩家交替的下红字Red或黄子Yellow。当丢下一子时,程序在控制台重新显示这个棋盘,然后确定游戏的状态(赢、平局还是继续)。运行效果如下图所示(只上传了前两张和后两张):
设计此题的时候需要考虑几个问题:1)如何模拟下子时只能下到每列的最下端的空位处;
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & 2)如果某一列满了,继续往该列下子要报错并提示重新输入;
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & 3)怎么设计判断方法,从而只需判断当前所下子的情况以确定胜负;
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & 4)怎么判断平局
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & 5)棋盘怎么刷新
& & & & 设计的时候可以自己先把每步的情况考虑清楚,如何用代码去实现,在纸上打个草稿,然后再开始写代码,并且每实现一个小的步骤都运行看看结果是否正确,正确之后再继续往下设计,这样可以减轻调试的负担,降低调试的难度,切记!
以下是实现的源代码:
package MutiA
import java.util.S
public class practice7Arrays{
//悬挂的四子棋
public static void main(String[]args){
Scanner input = new Scanner(System.in);
String[][] qi = new String[6][7];
String yuanShiYuanSu = &|
String yellow = &| Y &;
String red = &| R &;
int count = 0;//谁下子及下了多少子的判断计数器
//初始化棋子数组
for(int i = 0;i & qi.i++)
for(int j = 0;j & qi[0].j++)
qi[i][j] = yuanShiYuanSu;
//画出原始棋盘
System.out.println(&-----------------------------&);
for(int i = qi.length - 1;i &= 0;i--){
for(int j = 0;j & qi[0].j++)
System.out.print(qi[i][j]);
System.out.println(&|&);
System.out.println(&-----------------------------&);
for(int i = 0;i & qi[0].i++)
System.out.print(&* &+(i+1)+& &);
System.out.println(&*&);
int row = 0,column = 0;//行列下标初始化
//下棋循环开始
while (true) {
column = 0;
if (count % 2 == 0) {//黄方下子
System.out.print(&\n\nY player please drop a yellow disk at column(1~7):&);
while (true) {//黄方下子循环开始
column = input.nextInt() - 1;
if (column &= 0 && column &= 6) {// 输入合法进行下子
for (row = 0; row & qi. row++) {
if (qi[row][column] == yuanShiYuanSu) {
qi[row][column] =
if (row == qi.length)//该列棋子满,重新输入
System.out.print(&The column of you enter is full,&
+ &please reEnter! : &);
else//棋子没满,下子结束
else// 输入不合法,重新下子
System.out.print(&You enter the wrong column,&
+ &please reEnter! : &);
}//黄方下子循环结束
}//if(count % 2 == 0)
else{//红方下子
System.out.print(&\n\nR player please drop a yellow disk at column(1~7):&);
while (true) {//红方下子循环开始
column = input.nextInt() - 1;
if (column &= 0 && column &= 6) {// 输入合法进行下子
for (row = 0; row & qi. row++) {
if (qi[row][column] == yuanShiYuanSu) {
qi[row][column] =
if (row == qi.length)//该列棋子满,重新输入
System.out.print(&The column of you enter is full,&
+ &please reEnter! : &);
else//棋子没满,下子结束
else// 输入不合法,重新下子
System.out.print(&You enter the wrong column,&
+ &please reEnter! : &);
}//红方下子循环结束
}//if(count % 2 != 0)
//画出棋盘
System.out.println(&-----------------------------&);
for(int i = qi.length - 1;i &= 0;i--){
for(int j = 0;j & qi[0].j++)
System.out.print(qi[i][j]);
System.out.println(&|&);
System.out.println(&-----------------------------&);
for(int i = 0;i & qi[0].i++)
System.out.print(&* &+(i+1)+& &);
System.out.println(&*&);
//输赢标志位
boolean flagForYWin =
boolean flagForRWin =
//只需对当前下子的周围情况进行判断来决定棋局结果
if (count % 2 == 0) {//yellow player is win?
//行检测开始
if (column &= 3) {
for (int jj = 0; jj &= jj++)
if (qi[row][jj] == yellow
&& qi[row][jj + 1] == yellow
&& qi[row][jj + 2] == yellow
&& qi[row][jj + 3] == yellow) {
flagForYWin =
for (int jj = column - 3; jj &= 3; jj++)
if (qi[row][jj] == yellow
&& qi[row][jj + 1] == yellow
&& qi[row][jj + 2] == yellow
&& qi[row][jj + 3] == yellow) {
flagForYWin =
if (flagForYWin) {
System.out.println(&The yellow player win the game!&);
//列检测开始
if (row &= 3) {
if (qi[row][column] == yellow
&& qi[row - 1][column] == yellow
&& qi[row - 2][column] == yellow
&& qi[row - 3][column] == yellow)
flagForYWin =
if (flagForYWin) {
System.out.println(&The yellow player win the game!&);
//正反对角检测
if(row &= 3){
if(column & 3){
if (qi[row][column] == yellow
&& qi[row - 1][column + 1] == yellow
&& qi[row - 2][column + 2] == yellow
&& qi[row - 3][column + 3] == yellow)
flagForYWin =
else if(column & 3){
if (qi[row][column] == yellow
&& qi[row - 1][column - 1] == yellow
&& qi[row - 2][column - 2] == yellow
&& qi[row - 3][column - 3] == yellow)
flagForYWin =
if ((qi[row][column] == yellow
&& qi[row - 1][column + 1] == yellow
&& qi[row - 2][column + 2] == yellow
&& qi[row - 3][column + 3] == yellow)
|| (qi[row][column] == yellow
&& qi[row - 1][column - 1] == yellow
&& qi[row - 2][column - 2] == yellow
&& qi[row - 3][column - 3] == yellow))
flagForYWin =
if (flagForYWin) {
System.out.println(&The yellow player win the game!&);
}//yellow player is win?
else{//red player is win?
//行检测开始
if (column &= 3) {
for (int jj = 0; jj &= jj++)
if (qi[row][jj] == red
&& qi[row][jj + 1] == red
&& qi[row][jj + 2] == red
&& qi[row][jj + 3] == red) {
flagForRWin =
for (int jj = column - 3; jj &= 3; jj++)
if (qi[row][jj] == red
&& qi[row][jj + 1] == red
&& qi[row][jj + 2] == red
&& qi[row][jj + 3] == red) {
flagForRWin =
if (flagForRWin) {
System.out.println(&The red player win the game!&);
//列检测开始
if (row &= 3) {
if (qi[row][column] == red
&& qi[row - 1][column] == red
&& qi[row - 2][column] == red
&& qi[row - 3][column] == red)
flagForRWin =
if (flagForRWin) {
System.out.println(&The red player win the game!&);
//正反对角检测
if(row &= 3){
if(column & 3){
if (qi[row][column] == red
&& qi[row - 1][column + 1] == red
&& qi[row - 2][column + 2] == red
&& qi[row - 3][column + 3] == red)
flagForRWin =
else if(column & 3){
if (qi[row][column] == red
&& qi[row - 1][column - 1] == red
&& qi[row - 2][column - 2] == red
&& qi[row - 3][column - 3] == red)
flagForRWin =
if ((qi[row][column] == red
&& qi[row - 1][column + 1] == red
&& qi[row - 2][column + 2] == red
&& qi[row - 3][column + 3] == red)
|| (qi[row][column] == red
&& qi[row - 1][column - 1] == red
&& qi[row - 2][column - 2] == red
&& qi[row - 3][column - 3] == red))
flagForRWin =
if (flagForRWin) {
System.out.println(&The red player win the game!&);
count++;//棋子数加1,并用于谁下棋子的判断
//棋盘下满棋子,是平局
if(count == 6*7){
System.out.println(&棋盘棋子已经下满,是平局!&);
}//下棋循环结束
& & & & 至此Java最基本的知识就基本练习完毕了,接下来就是其他思想和类、对象、重载、多态、继承、GUI等的学习了。尤其是GUI的学习,是在其他学习打下基础之后进行的,也是Java中最炫酷的一部分!所以得将基础打牢,勤加练习、多加练习!
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:22015次
排名:千里之外
原创:45篇
评论:10条
(3)(26)(1)(22)四子棋的介绍_百度知道四子棋AI设计 四子棋
四子棋AI设计实验报告实验简介&p style = "padding-left:2px"&本次实验要求实现一个变种四子棋的AI,以期能战胜人类玩家以及其他AI。本次实验的特色在于,它不是经典的四子棋,有如下几方面的调整。&/p&棋盘大小是随机的,并且比经典的棋盘要大不少。(经典的棋盘是6*7的,而本次的棋盘的行和列都是[9,12]的)。棋盘上有一个不可落子点,任何子都不能落在上面,并且它会阻碍棋子的连通。这么一来,就消除了在任何情况下都存在必胜策略的可能性。我们所要做的,就是给出任何棋盘和不可落子位分布下通用的AI算法。实验难点及解决方法本次实验的难点在于,如果用实验指导里所写的alpha-beta剪枝算法,那么估价函数是很需要设计的。而由于棋盘的大小不定,且有随机落子点,所以如果要写一个能够很好地反映局面的估价函数并不容易。在最开始的时候,我写了alpha-beta剪枝的版[www.nIuBB.NET]本,但由于估价函数不好,只能战胜50.dll,于是我觉得这个方法改进很是麻烦。比拼智力的事情应该是人做的,怎么能让机器做呢!然后,不久,我就听说了蒙特卡洛算法――对每个点随机落子模拟至比赛结束,选出胜率最高的落子位作为下子的地方。听起来十分有道理,但是这里有个问题就是双方是随机落子,并不是最优解,所以收敛效果差,加上每步限时5s,难以收敛。(当然,实际上传统的蒙特卡洛算法几乎连稍好些的alpha-beta剪枝都没办法战胜,我写的第二版纯蒙特卡洛程序连40.dll都战得吃力。)就在这时,我听闻了蒙特卡洛树搜索算法(Mento-Carlo Tree Search,下文简称MCTS)。和舍友宋佳铭进行讨论后,一致认为这个算法还是很靠谱的,因为双方都是根据最优走法来行动,并且以空间换时间(实验中并未限制内存的使用,只要不泄露就可以了),这样收敛效率和迭代次数都得以增加。所以,最后的关键就在于如何让程序算得更快一些。我将整个程序的运行时间卡在4.5秒,如何在这4.5秒内进行尽可能多轮的迭代就成为了胜败的关键条件。
一开始,我查找了网上的资料,看了伪代码和一些java和C#的源码,写出了面向对象版本的程序――后来发现,这是很愚蠢的做法,至少在这次的实验中。面向对象的写法好看归好看,高扩展归高扩展,但它慢啊!这个版本只能战胜80.dll,每次只能迭代几万次。最后,我终于忍不住把所有的程序改成了面向对象的版本,效果拔群。在我的机器配置(CPU:Intel 3630QM 八核处理器,内存 8G)下,平均每一轮能迭代80万次,生成700万个节点。这样,跟100.dll进行对战,胜率也能超过60%。但还是要说一点,如果alpha-beta剪枝的估价函数写得非常好,那么这点时间下MCTS还是不足以击败它的。并且,alpha-beta剪枝的出解速度也非MCTS可比。只不过,MCTS是以机器的优势在和人较量罢了。算法流程1、初始化棋局,以-1为父节点nf,扩展第一层子节点,每个节点代表一个可行位。2、对于nf的每个子节点ni,用UCB公式算出其UCB值,选取UCT值最大的节点nl。3、如果nl不是叶子节点,那么以它为父节点nf,转2。4、如果nl是叶子节点,那么将它进行模拟对局,向上更新每一个节点的赢盘值winRound和总盘值totRound,如果对局成功并且游戏还没有结束,那么为它扩展子节点。5、如果不满足终止条件(本程序中为经过的时间小于4.5s),那么以-1为父节点,转2。6、在以-1为父节点的子节点,选取胜率最高也即winRound/totRound值最大的节点,作为落子点。程序关键细节MCTNode类MCTNode类是程序中记录每一个节点的信息的类。具体信息如下。class MCTNode{//蒙特卡洛树节点public:
int LChild,RChild,//记录最左孩子和最右孩子的位置,以及父节点的位置。
int x,y;//当前节点表示下子在哪里。
bool isLeaf,//isLeaf用以判断当前节点是否是叶子节点;user为true,则为本方行走;user为false,则为对方行走。
int winRound,totR//胜盘数以及总盘数};节点扩展函数void expand(int fIndex,const int *top){//以fIndex为父节点,top为当前可落子位的依据,扩展子节点
for(int i = 0; i & NN; i++)
if(top[i] & 0){
nodes[Index].isLeaf =//确立为叶节点
nodes[Index].winRound = 0;//初始总赢盘为0
nodes[Index].totRound = 0;//初始总负盘为0
nodes[Index].father = fI//父节点为根节点
nodes[Index].user = !nodes[fIndex].//这轮是对方行走
nodes[Index].x = top[i] -1;//下子的行序
nodes[Index].y =//下子的列序
++I//让下标加1
nodes[fIndex].RChild = I//确立右孩子的位置}UCT值计算公式double getUCB(int index,int fIndex){//UCB公式(细节:epsilon=1e-6是为了防止除0,第二项的+1亦然)
return (double)nodes[index].winRound/((double)nodes[index].totRound+epsilon) +
C*((double)log((double)nodes[fIndex].totRound+1)/((double)nodes[index].totRound+epsilon))+rand()*}加速方法const int MAXTREE = 8500050;//最大树规模int Index = 0;//树下标int no_X,no_Y,NN,MM;//不可落子点,由程序中的noX,noY获得,记在全局中方便使用。int **tempBoard,**tempBoard2;//记录临时棋局int *tempTop,*tempTop2;//记录临时顶端MCTNode nodes[MAXTREE];//蒙特卡洛树使用静态数组众所周知,创建指针和释放内存都是十分耗时的事情,而本次实验并不限定内存的使用,所以我在程序的开始就建立了一个大小为MAXTREE=8500050的MCTNode数组来模拟树状结构,再以MCTNode类中的一些参数来进行层间控制。这样,可以避免链表创建和销毁时的消耗,又能保证路径的连续性。欢迎您转载分享:
更多精彩:,,&&&&三维四子棋
三维四子棋
原型来自中国科技馆。采用OpenGL编程实现,可以锻炼空间想象力和三维上的逻辑思考能力,同时辅助空间立体几何的教学。
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
VIP下载&&免积分60元/年(1200次)
您可能还需要
课程资源下载排行}

我要回帖

更多关于 城市四子棋 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信