C语言编写的黑白棋游戏源代码

合集下载

简易黑白棋c++代码

简易黑白棋c++代码
{
for (int j = 0;j < board_length;j++)
{
if (Board[i][j] == black)
countb++;
if (Board[i][j] == white)
countw++;
}
}
if (countb > countw)
if (inBoard(x2 + dir_x[i], y2 + dir_y[i]) && Board[x2 + dir_x[i]][y2 + dir_y[i]] == color)
{
do {
Board[x2][y2] = color;
x2 -= dir_x[i];
cout << "黑胜" << endl;
else if (countb < countw)
cout << "白胜" << endl;
else
cout << "平局" << endl;
}
{
addWhite();
show();
}
}
panduan();
}
//判断输赢
void Heibaiqi::panduan()
{
int countb = 0, countw = 0;
for (int i = 0;i < board_length;i++)
return true;

五子棋代码C语言版

五子棋代码C语言版

#include <stdlib.h>#include <stdio.h>#include <conio.h>#include <string.h>#include <malloc.h>struct rcd;//声明节点结构typedef struct rcd* Record;//节点指针别名typedef struct rcd record;//节点别名#define MAXIMUS 15 //定义棋盘大小int p[MAXIMUS][MAXIMUS];//存储对局信息char buff[MAXIMUS*2+1][MAXIMUS*4+3];//输出缓冲器int Cx,Cy;//当前光标位置int Now;//当前走子的玩家,1代表黑,2代表白int wl,wp;//当前写入缓冲器的列数和行数位置char* showText;//在棋盘中央显示的文字信息int count;//回合数int Putable;//指示当前是否可以走棋int Exiting;//1为当场上无子并按ESC时询问是否退出程序的状态,2为非此状态int ExiRep;//1为当回放到最后一回合并按向后时询问是否退出回放的状态,2为非此状态Record RecBeg,RecNow;//记录的开始节点和当前节点struct rcd//记录节点结构,双链表形式{int X;//此记录走棋的X坐标int Y;//此记录走棋的Y坐标Record Next;//前一个记录Record Back;//后一个记录};Record newRecord()//记录节点构造函数{Record r=(Record)malloc(sizeof(record));//申请一个节点对象r->Next=NULL;//给予前后节点初值NULLr->Back=NULL;return r;}void Exit()//检查退出程序{int input;if(Exiting)//如果是第二次按下ESC{exit(0);}else//如果是第一次按下ESC则询问是否退出程序{showText="是否退出?再次按下ESC退出,其他键返回";Exiting=1;//指示已经按下过ESC}}void ExitRep()//检查退出回放{int input;if(ExiRep)//如果是第二次后移{ExiRep=3;}else//如果是第一次后移则询问是否退出回放{showText="是否退出?再次后移退出回放,其他键返回";ExiRep=1;//指示已经按下过后移}}void AddRecord()//添加记录{RecNow->X=Cx;//记录坐标RecNow->Y=Cy;RecNow->Next=newRecord();//创建下一个记录节点RecNow->Next->Back=RecNow;//完成双链表RecNow=RecNow->Next;//当前记录推至下一个记录节点}int DelRecord()//删除当前记录节点,1为删除成功,0为删除失败{Record b;//上一个节点if(RecNow->Back!=NULL)//越界检查{b=RecNow->Back;//缓存上一个节点free(RecNow);//释放当前节点RecNow=b;//当前记录回至上一个记录节点return 1;}else{return 0;//没有节点可删除时}}void CleanRecord()//清理所有记录{Record n;//下一个节点while(RecBeg->Next!=NULL)//删除所有记录,直到越界前为止{n=RecBeg->Next;//记下下一个节点free(RecBeg);//释放当前节点RecBeg=n;//当前记录推至下一个记录节点}}char* Copy(char* strDest,const char* strSrc)//修改过的字符串复制函数,会忽略末端的\0 {char* strDestCopy = strDest;while (*strSrc!='\0'){*strDest++=*strSrc++;}return strDestCopy;}void Initialize()//初始化一个对局函数{int i,j;//循环变量system("title 对局中(按方向键控制光标,空格走子),Esc撤销");showText="";//重置显示信息count=0;//回合数归零RecNow=RecBeg=newRecord();Exiting=0;for(i=0;i<MAXIMUS;i++)//重置对局数据{for(j=0;j<MAXIMUS;j++){p[i][j]=0;}}Cx=Cy=MAXIMUS/2;//重置光标到中央Now=1;//重置当前为黑方}char* getStyle(int i,int j)//获得棋盘中指定坐标交点位置的字符,通过制表符拼成棋盘{if(p[i][j]==1)//1为黑子return "●";else if(p[i][j]==2)//2为白子return "○";else if(i==0&&j==0)//以下为边缘棋盘样式return "┏";else if(i==MAXIMUS-1&&j==0)return "┓";else if(i==MAXIMUS-1&&j==MAXIMUS-1)return "┛";else if(i==0&&j==MAXIMUS-1)return "┗";else if(i==0)return "┠";else if(i==MAXIMUS-1)return "┨";else if(j==0)return "┯";else if(j==MAXIMUS-1)return "┷";return "┼";//中间的空位}char* getCurse(int i,int j){//获得指定坐标交点位置左上格的样式,通过制表符来模拟光标的显示if(Putable)//可走棋时光标为粗线{if(i==Cx){if(j==Cy)return "┏";else if (j==Cy+1)return "┗";}else if(i==Cx+1){if(j==Cy)return "┓";else if (j==Cy+1)return "┛";}}else//不可走棋时光标为虚线{if(i==Cx){if(j==Cy)return "┌";else if (j==Cy+1)return "└";}else if(i==Cx+1){if(j==Cy)return "┐";else if (j==Cy+1)return "┘";}}return "";//如果不在光标附近则为空}void write(char* c)//向缓冲器写入字符串{Copy(buff[wl]+wp,c);wp+=strlen(c);}void ln()//缓冲器写入位置提行{wl+=1;wp=0;}void Display()//将缓冲器内容输出到屏幕{int i,l=strlen(showText);//循环变量,中间文字信息的长度int Offset=MAXIMUS*2+2-l/2;//算出中间文字信息居中显示所在的横坐标位置if(Offset%2==1)//如果位置为奇数,则移动到偶数,避免混乱{Offset--;}Copy(buff[MAXIMUS]+Offset,showText);//讲中间文字信息复制到缓冲器if(l%2==1)//如果中间文字长度为半角奇数,则补上空格,避免混乱{*(buff[MAXIMUS]+Offset+l)=0x20;}system("cls");//清理屏幕,准备写入for(i=0;i<MAXIMUS*2+1;i++){//循环写入每一行printf("%s",buff[i]);if(i<MAXIMUS*2)//写入完每一行需要换行printf("\n");}}void Print()//将整个棋盘算出并储存到缓冲器,然后调用Display函数显示出来{int i,j;//循环变量wl=0;wp=0;for(j=0;j<=MAXIMUS;j++)//写入出交点左上角的字符,因为需要打印棋盘右下角,所以很以横纵各多一次循环{for(i=0;i<=MAXIMUS;i++){write(getCurse(i,j));//写入左上角字符if(j==0||j==MAXIMUS)//如果是棋上下盘边缘则没有连接的竖线,用空格填充位置{if(i!=MAXIMUS)write("");}else//如果在棋盘中间则用竖线承接上下{if(i==0||i==MAXIMUS-1)//左右边缘的竖线更粗write("┃");else if(i!=MAXIMUS)//中间的竖线write("│");}}if(j==MAXIMUS)//如果是最后一次循环,则只需要处理边侧字符,交点要少一排{break;}ln();//提行开始打印交点内容write("");//用空位补齐位置for(i=0;i<MAXIMUS;i++)//按横坐标循环正常的次数{write(getStyle(i,j));//写入交点字符if(i!=MAXIMUS-1)//如果不在最右侧则补充一个横线承接左右{if(j==0||j==MAXIMUS-1){write("━");//上下边缘的横线更粗}else{write("─");//中间的横线}}}ln();//写完一行后提行}Display();//将缓冲器内容输出到屏幕}int Put(){//在当前光标位置走子,如果非空,则返回0表示失败if(Putable){p[Cx][Cy]=Now;//改变该位置数据AddRecord();return 1;//返回1表示成功}else{return 0;}}int Check()//胜负检查,即判断当前走子位置有没有造成五连珠的情况{int w=1,x=1,y=1,z=1,i;//累计横竖正斜反邪四个方向的连续相同棋子数目for(i=1;i<5;i++)if(Cy+i<MAXIMUS&&p[Cx][Cy+i]==Now)w++;else break;//向下检查for(i=1;i<5;i++)if(Cy-i>0&&p[Cx][Cy-i]==Now)w++;else break;//向上检查if(w>=5)return Now;//若果达到5个则判断当前走子玩家为赢家for(i=1;i<5;i++)if(Cx+i<MAXIMUS&&p[Cx+i][Cy]==Now)x++;else break;//向右检查for(i=1;i<5;i++)if(Cx-i>0&&p[Cx-i][Cy]==Now)x++;else break;//向左检查if(x>=5)return Now;//若果达到5个则判断当前走子玩家为赢家for(i=1;i<5;i++)if(Cx+i<MAXIMUS&&Cy+i<MAXIMUS&&p[Cx+i][Cy+i]==Now)y++;else break;//向右下检查for(i=1;i<5;i++)if(Cx-i>0&&Cy-i>0&&p[Cx-i][Cy-i]==Now)y++;else break;//向左上检查if(y>=5)return Now;//若果达到5个则判断当前走子玩家为赢家for(i=1;i<5;i++)if(Cx+i<MAXIMUS&&Cy-i>0&&p[Cx+i][Cy-i]==Now)z++;else break;//向右上检查for(i=1;i<5;i++)if(Cx-i>0&&Cy+i<MAXIMUS&&p[Cx-i][Cy+i]==Now)z++;else break;//向左下检查if(z>=5)return Now;//若果达到5个则判断当前走子玩家为赢家return 0;//若没有检查到五连珠,则返回0表示还没有玩家达成胜利}void ReplayMode(){int i,j;//循环变量system("title 回放中(按左键后退,右键或空格前进),Esc退出");showText="";//重置显示信息count=0;//回合数归零Putable=0;//不可走棋状态RecBeg->Back=newRecord();RecBeg->Back->Next=RecBeg;RecBeg=RecBeg->Back;for(i=0;i<MAXIMUS;i++)//重置对局数据{for(j=0;j<MAXIMUS;j++){p[i][j]=0;}}Now=1;//重置当前为黑方}void RepForward()//回放模式前进{if(RecNow->Next->Next!=NULL)//越界检查{RecNow=RecNow->Next;//当前节点推至下一个记录节点p[RecNow->X][RecNow->Y]=Now;//按照记录还原一个回合Cx=RecNow->X;//设置光标位置Cy=RecNow->Y;Now=3-Now;//转换当前的黑白方}else//若已达到最后则询问退出{ExitRep();}}void RepBackward()//回放模式后退{if(RecNow->Back!=NULL)//越界检查{p[RecNow->X][RecNow->Y]=0;//按照记录撤销一个回合if(RecNow->Back->Back==NULL)//在整个棋盘没有棋子时隐藏光标{Cx=-2;Cy=-2;}else if(RecNow->Back==NULL)//在只有一个棋子时移动光标到这个棋子的位置{Cx=RecNow->X;Cy=RecNow->Y;}else//正常情况下移动光标到上一回合的位置{Cx=RecNow->Back->X;Cy=RecNow->Back->Y;}RecNow=RecNow->Back;//当前节点后退至上一个记录节点Now=3-Now;//转换当前的黑白方}}void ShowReplay(){int input;//输入变量ReplayMode();//初始化回放模式RecNow=RecBeg;//当前观察从头开始RepForward();//显示第一次走棋while(1)//开始无限回合的死循环,直到Esc退出{if(ExiRep==3){ExiRep=0;break;}Print();//打印棋盘input=getch();//等待键盘按下一个字符if(input==27)//如果是ESC则退出回放{return;}else if(input==0x20)//如果是空格则前进{RepForward();continue;}else if(input==0xE0)//如果按下的是方向键,会填充两次输入,第一次为0xE0表示按下的是控制键{input=getch();//获得第二次输入信息switch(input)//判断方向键方向并移动光标位置{case 0x4B:RepBackward();//向左后退break;case 0x4D:RepForward();//向右前进continue;}}ExiRep=0;//未再次按后移则不准备退出showText="";}}void Regret()//悔棋撤销,如果棋盘上没有子即为退出{if(DelRecord()){//尝试删除当前节点,如果有节点可以删除则p[RecNow->X][RecNow->Y]=0;//撤除当前回合if(RecNow->Back==NULL)//如果删除的是第一颗子则将光标移动到第一颗子原来的位置上{Cx=RecNow->X;Cy=RecNow->Y;}else//否则将光标移动到上一颗子上{Cx=RecNow->Back->X;Cy=RecNow->Back->Y;}Now=3-Now;//反转当前黑白方}else{Exit();//如果没有棋子可以撤销,则询问退出}}int RunGame()//进行整个对局,返回赢家信息(虽然有用上){int input;//输入变量int victor;//赢家信息Initialize();//初始化对局while(1){//开始无限回合的死循环,直到出现胜利跳出Putable=p[Cx][Cy]==0;Print();//打印棋盘input=getch();//等待键盘按下一个字符if(input==27)//如果是ESC则悔棋或退出{Regret();Print();continue;}else if(input==0x20)//如果是空格则开始走子{if(Put())//如果走子成功则判断胜负{victor=Check();Now=3-Now;//轮换当前走子玩家count++;if(victor==1)//如果黑方达到胜利,显示提示文字并等待一次按键,返回胜利信息{showText="黑方胜利!按R查看回放,按其他键重新开局";Print();input=getch();if(input==0xE0){getch();}else if(input=='R'||input=='r'){ShowReplay();}return Now;}else if(victor==2)//如果白方达到胜利,显示提示文字并等待一次按键,返回胜利信息{showText="白方胜利!按R查看回放,按其他键重新开局";Print();input=getch();if(input==0xE0)getch();}else if(input=='R'||input=='r'){ShowReplay();}return Now;}else if(count==MAXIMUS*MAXIMUS)//如果回合数达到了棋盘总量,即棋盘充满,即为平局{showText="平局!按R查看回放,按其他键重新开局";Print();input=getch();if(input==0xE0){getch();}else if(input=='R'||input=='r'){ShowReplay();}CleanRecord();return 0;}}}else if(input==0xE0)//如果按下的是方向键,会填充两次输入,第一次为0xE0表示按下的是控制键{input=getch();//获得第二次输入信息switch(input)//判断方向键方向并移动光标位置{case 0x4B://Cx--;break;case 0x48:Cy--;break;case 0x4D:Cx++;break;case 0x50:Cy++;}if(Cx<0)Cx=MAXIMUS-1;//如果光标位置越界则移动到对侧if(Cy<0)Cy=MAXIMUS-1;if(Cx>MAXIMUS-1)Cx=0;if(Cy>MAXIMUS-1)Cy=0;}Exiting=0;//未再次按下ESC则不准备退出showText="";}}int main()//主函数{system("mode con cols=63 lines=32");//设置窗口大小system("color E0");//设置颜色while(1){//循环执行游戏RunGame();}}。

黑白棋代码

黑白棋代码

01.var AI = {};02.new function(){03.AI.Pattern= pattern;04.// 定义了 8 个偏移量05.// 可以简单通过加法得到任一点周围 8 个点的坐标06.// -11 -10 -907.// -1 x 108.// 9 10 1109.// 如左上角的坐标为 x + (-11)10.var directions=[-11,-10,-9,-1,1,9,10,11];11.function pattern()12.{13. // 把整个棋盘填满 014. for(var i=0;i<100;i++)this[i]=0;15. // 中间的 4 个格子,先放上两黑两白的棋子16. this[54]=this[45]=1;this[55]=this[44]=2;17. // 黑净胜外围子数目(黑减去白),估值时用。

18. this.divergence=0;19. // 当前可走棋方为黑棋20. this.color=1;21. // 已经走了几步棋22. this.moves=0;23. // 稳定原型24. // 0 是空白,1 是黑棋,2 是白棋,3 是边界25. // 把 8 * 8 的棋盘扩展成 10 * 10,是一种技巧26. // 可以简化坐标有效性的判断27. var stableProto = [28. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,29. 3, 0, 0, 0, 0, 0, 0, 0, 0, 3,30. 3, 0, 0, 0, 0, 0, 0, 0, 0, 3,31. 3, 0, 0, 0, 0, 0, 0, 0, 0, 3,32. 3, 0, 0, 0, 0, 0, 0, 0, 0, 3,33. 3, 0, 0, 0, 0, 0, 0, 0, 0, 3,34. 3, 0, 0, 0, 0, 0, 0, 0, 0, 3,35. 3, 0, 0, 0, 0, 0, 0, 0, 0, 3,36. 3, 0, 0, 0, 0, 0, 0, 0, 0, 3,37. 3, 3, 3, 3, 3, 3, 3, 3, 3, 338. ]39. // 从一个 8 * 8 的棋盘载入状态40. this.load=function(arr)41. {42. for(var y=1;y<=8;y++)43. {44. for(var x=1;x<=8;x++)45. {46. this[y*10+x]=arr[y-1][x-1];47. }48. }49. }50. // 判断能不能 pass51. // 如果能,则当前可走棋方变更52. this.pass=function()53. {54. for(var y=1;y<=8;y++)55. {56. for(var x=1;x<=8;x++)57. {58. if(this[y*10+x]==0)59. {60. // 有任何一步棋可走,都不可以 Pass61. if(this.move(x,y,this.color))62. {63. return false;64. }65. }66. }67. }68. //alert("pass");69. // 这是一个技巧,因为 this.color 的值域是 {1, 2}70. // 所以当 color 是 1 时,执行完下一语句后就是 271. // 当 color 是 2 时,执行完下一语句后就是 172. this.color = 3 - this.color;73. return true;74. }75. this.clone=function()76. {77. function pattern(){}78. pattern.prototype=this;79. return new pattern();80. }81. this.toString=function()82. {83. var icon=[" ","*","o"]84. var r="";85. for(var y=1;y<=8;y++)86. {87. for(var x=1;x<=8;x++)88. {89. r+=icon[this[y*10+x]]+" ";90. //r+=stableDiscs[y*10+x]+" ";91. }92. r+="\n";93. }94. return r+this.exact();95. }96.97. // 净胜子数98. this.exact=function()99. {100. // 这里是一个技巧, r[0] 是不使用的,r[1] r[2] 对应黑白棋子的个数101. var r=[0,0,0];102. for(var y=1;y<=8;y++)103. {104. for(var x=1;x<=8;x++)105. {106. r[this[y*10+x]]++; // 数目加一107. }108. }109. // 当前颜色的数量为 0,输了,返回负极值110. if(r[this.color]==0) return -64;111. // 敌对颜色的数量为 0,赢了,返回极值112. if(r[3-this.color]==0) return 64;113. // 返回当前走棋方比对方多的数量114. return r[this.color]-r[3-this.color];115. }116. // 对棋盘的估值117. this.calculate=function()118. {119. // 基本估值方法:120. // 1、能占棋盘四角是很有价值的121. // 2、邻近棋盘四角的位子是很差的122. // 3、稳定子123. // 4、外围子净胜数124. var r=[0,0,0];125. var r=this.divergence;126. // 如果左上角有棋子,自己的,就+30分,敌方的,-30 分127. if(this[11]) r+=((this[11]==this.color)?1:-1)*30;128. // 次左上角,分值是 -15129. else if(this[22]==this.color)r-=15;130. // 右上角,分值 30131. if(this[18])r+=((this[18]==this.color)?1:-1)*30;132. // 次右上角,分值 -15133. else if(this[27]==this.color)r-=15;134. // 左下角,分值 30135. if(this[81])r+=((this[81]==this.color)?1:-1)*30;136. // 次左下角,分值 -15137. else if(this[72]==this.color)r-=15;138. // 右下角,分值 30139. if(this[88]){r+=((this[88]==this.color)?1:-1)*30;}140. // 次右下角,分值 -15141. else if(this[77]==this.color)r-=15;142. // 查找稳定子,143. // 稳定子就是挨着 4 个角点并且周边的棋子要么是同色,要么是边界144. //var color = this.color;145. var stableDiscs=stableProto.slice();146.147. var queue = [];148. if(this[11]!=0) queue.push([11,this[11]]);149. if(this[18]!=0) queue.push([18,this[18]]);150. if(this[81]!=0) queue.push([81,this[81]]);151. if(this[88]!=0) queue.push([88,this[88]]);152. while(queue.length)153. {154. var position = queue[0][0];155. var c = queue[0][1];156. // 不懂 JS 的数组的内存管理算法,不过感觉从头上删除肯定是比较慢的,157. // 我感觉从后面删除会更好,或者使用标记不删除的方法性能会更好158. queue.shift();159. //if(stableDiscs[position]==0 || stableDiscs[position]==3) continue;160. stableDiscs[position] = c;161. if( (stableDiscs[position-10]==3 || stableDiscs[position+10]==3 || stableDiscs[position-10] == c || stableDiscs[position+10] == c) &&162. (stableDiscs[position-1]==3 || stableDiscs[position+1]==3 || stableDiscs[position-1] == c || stableDiscs[position+1] == c) &&163. (stableDiscs[position-11]==3 || stableDiscs[position+11]==3 || stableDiscs[position-11] == c || stableDiscs[position+11] == c) &&164. (stableDiscs[position-9]==3 || stableDiscs[position+9]==3 || stableDiscs[position-9] == c || stableDiscs[position+9] == c) )165. {166. stableDiscs[position]=c;167. // 稳定子的分值为 7168. r += ((c==this.color)?1:-1)*7;169. // 进一步扩展,查找稳定子170. for(var i = 0;i <directions.length ; i++)171. if(stableDiscs[directions[i]+position]==0 && this[directions[i]+position]==c)172. queue.push([directions[i]+position,c]);173. }174. }175.176. // 返回估值177. return r;178. }179. this.toLocalString=function(depth)180. {181. var r="";182. if(!depth)depth=0;183.184. for(var y=1;y<=8;y++)185. {186. for(var x=1;x<=8;x++)187. {188. if(this[y*10+x]!=0)r+=(this[y*10+x]==1?"*":"o")+" "; 189. else190. {191. var tmp=this.move(x,y,this.color);192. if(tmp)193. {194. var tmp2=-tmp.search(-Infinity,Infinity,depth); 195. if(tmp2<0||tmp2>9)r+=tmp2;196. else r+=" "+tmp2;197. }198. else r+="X ";199. }200. }201. r+="\n";202. }203. return r+this.exact();204. }205. // 计算机去找一步可走的棋步206. // 这里 AI 部分的入口207. puter=function(depth,exactDepth){208. if(!depth)depth=0;209. if(!exactDepth)exactDepth=depth;210. var r=[];211. var max=-Infinity;212. for(var y=1;y<=8;y++)213. {214. for(var x=1;x<=8;x++)215. {216. if(this[y*10+x])continue;217. // 找到一个空白格子218. else219. {220. // 尝试走这个格子221. var tmp=this.move(x,y,this.color);222. // 不成功,非法223. if(!tmp)continue;224. // 已走步数+已搜索深度 >= 有 60 步225. // 这时使用精确搜索得到更精确的结果226. if(this.moves+exactDepth>=60)227. {228. var v=-tmp.exactSearch(-Infinity,Infinity);229. //alert([x,y]+":"+v);230. }231. // 离四个角最近的那 3 * 4 个格子,则多搜索一层232. // 因为对手可能在下一手下在角上,会出现大翻盘。

C语言-黑白棋(人机对战)

C语言-黑白棋(人机对战)

C语⾔-⿊⽩棋(⼈机对战)1 #include <stdio.h>2 #include <stdlib.h>3/*4具体思路如下:51.定义⼀个⼆维数组chessboard[8][8],⽤于保存⿊⽩双⽅棋⼦的位置。

如果数组元素为0,表⽰该单元格未落⼦;如果是-1,表⽰该单元格是⿊⼦;如果是1,则表⽰该单元格是⽩⼦。

62.当⼀⽅下棋时,先检查是否有位置可下,如果有则⼰⽅下棋,如果没有就让对⼿下棋。

73.若玩家下,需要等待玩家输⼊棋⼦坐标,然后执⾏翻转对⼿棋⼦操作。

84.若计算机下,程序需对棋盘所有可以落⼦的位置进⾏判断,找出最佳的落⼦位置,然后执⾏翻转对⼿棋⼦操作。

95.重复步骤2~4,直到棋盘已满或双⽅都不能下⼦时结束。

10*/1112void Output(char chessboard[][8]); //显⽰棋盘中的下⼦情况13int Check(char chessboard[][8],int moves[][8],char player);//检查⼀⽅是否有位置下⼦14void PlayStep(char chessboard[][8],int row,int col,char player);//在指定位置下棋15void AutoPlayStep(char chessboard[][8],int moves[][8],char player);//计算机思考下⼦16int GetMaxScore(char chessboard[][8],char player);//获取分数17int BestPlay(char chessboard[][8],int moves[][8],char player);//最优下⼦位置181920int main(){21char chessboard[8][8];//保存棋盘中各单元格下⼦的状态22int isDown[8][8] = {0};//保存棋盘中的各个位置是否可以下⼦,可以下的位置为1,其余为023int row,col,x,y;24int iCount = 0;//以下⼦的数量25int player = 0;//下棋⽅26int SkipPlay = 0;//重置下⼦的次数为0,若为2,则表⽰双⽅都不能下⼦27int Score[2];//保存计算机和玩家的得分2829char select,ch;3031 printf("⿊⽩棋\n\n");32 printf("玩家执⿊⼦先⾏,计算机执⽩,按Enter开始\n");333435 scanf("%c",&select);3637do{3839if(player==0){40 player = 1;41 }else{42 player = 0;43 }4445for(row=0;row<8;row++){46for(col=0;col<8;col++){47 chessboard[row][col]=0;48 }49 }5051 iCount = 4;//游戏开始的四颗棋⼦52 chessboard[3][3] = chessboard[4][4] = 1;53 chessboard[3][4] = chessboard[4][3] = -1;5455 printf("\n棋盘初始状态:\n");56 Output(chessboard);5758//双⽅下棋59do{60if(player==1){//玩家下棋(⿊)61 player = 0;62if(Check(chessboard,isDown,2)){63while(1){64 fflush(stdin);65 printf("输⼊下⼦的位置(⾏,列):");66 scanf("%d%c",&x,&ch);67 x--;//因为数组是从0开始存的68if(ch>='a'){69 y = ch - 'a' + 1;70 } else{71 y = ch - 'A' + 1;72 }73 y--;74//判断是否越界、是否已有棋⼦75if(x>=0&&x<8&&y>=0&&y<8&&isDown[x][y]){76 PlayStep(chessboard,x,y,2);77 iCount++;78break;79 }else{80 printf("坐标输⼊有误,请重新输⼊。

C语言编写象棋程序代码上课讲义

C语言编写象棋程序代码上课讲义

C语言编写象棋程序代码/*--------------------chess.c----------------------*/ #include "dos.h"#include "stdio.h"/*----------------------------------------------------*/ #define RED 7#define BLACK 14#define true 1#define false 0#define SELECT 0#define MOVE 1#define RED_UP 0x1100#define RED_DOWN 0x1f00#define RED_LEFT 0x1e00#define RED_RIGHT 0x2000#define RED_DO 0x3900#define RED_UNDO 0x1000#define BLACK_UP 0x4800#define BLACK_DOWN 0x5000#define BLACK_LEFT 0x4b00#define BLACK_RIGHT 0x4d00#define BLACK_DO 0x1c00#define BLACK_UNDO 0x2b00#define ESCAPE 0x0100#define RED_JU 1#define RED_MA 2#define RED_XIANG 3#define RED_SHI 4#define RED_JIANG 5#define RED_PAO 6#define RED_BIN 7#define BLACK_JU 8#define BLACK_MA 9#define BLACK_XIANG 10#define BLACK_SHI 11#define BLACK_JIANG 12#define BLACK_PAO 13#define BLACK_BIN 14/*----------------------------------------------------*/ int firsttime=1;int savemode;char page_new=0,page_old=0;int finish=false,turn=BLACK,winner=0;int key;int redstate=SELECT,blackstate=SELECT;int board[10][9];/*----------------------------------------------------*/char *chessfile[15]={"","bmp\\rju.wfb", "bmp\\rma.wfb","bmp\\rxiang.wfb","bmp\\rshi.wfb","bmp\\rjiang.wfb","bmp\\rpao.wfb","bmp\\rbin.wfb","bmp\\bju.wfb", "bmp\\bma.wfb","bmp\\bxiang.wfb","bmp\\bshi.wfb","bmp\\bjiang.wfb","bmp\\bpao.wfb","bmp\\bbin.wfb"};char *boardfile[10][9]={{"bmp\\11.wfb","bmp\\1t.wfb","bmp\\1t.wfb","bmp\\14.wfb","bmp\\15.wfb","bmp\\1 6.wfb","bmp\\1t.wfb","bmp\\1t.wfb","bmp\\19.wfb"},{"bmp\\21.wfb","bmp\\2c.wfb","bmp\\2c.wfb","bmp\\24.wfb","bmp\\25.wfb","bmp\\ 26.wfb","bmp\\2c.wfb","bmp\\2c.wfb","bmp\\29.wfb"},{"bmp\\21.wfb","bmp\\3a.wfb","bmp\\3t.wfb","bmp\\34.wfb","bmp\\3t.wfb","bmp\\3 6.wfb","bmp\\3t.wfb","bmp\\3a.wfb","bmp\\29.wfb"},{"bmp\\41.wfb","bmp\\4t.wfb","bmp\\4a.wfb","bmp\\4t.wfb","bmp\\4a.wfb","bmp\\4t .wfb","bmp\\4a.wfb","bmp\\4t.wfb","bmp\\49.wfb"},{"bmp\\51.wfb","bmp\\52.wfb","bmp\\5t.wfb","bmp\\54.wfb","bmp\\5t.wfb","bmp\\5 6.wfb","bmp\\5t.wfb","bmp\\58.wfb","bmp\\59.wfb"},{"bmp\\61.wfb","bmp\\62.wfb","bmp\\6t.wfb","bmp\\64.wfb","bmp\\6t.wfb","bmp\\6 6.wfb","bmp\\6t.wfb","bmp\\68.wfb","bmp\\69.wfb"},{"bmp\\71.wfb","bmp\\7t.wfb","bmp\\7a.wfb","bmp\\7t.wfb","bmp\\7a.wfb","bmp\\7t .wfb","bmp\\7a.wfb","bmp\\7t.wfb","bmp\\79.wfb"},{"bmp\\81.wfb","bmp\\8a.wfb","bmp\\8t.wfb","bmp\\84.wfb","bmp\\85.wfb","bmp\\8 6.wfb","bmp\\8t.wfb","bmp\\8a.wfb","bmp\\89.wfb"},{"bmp\\91.wfb","bmp\\9t.wfb","bmp\\9t.wfb","bmp\\9t.wfb","bmp\\95.wfb","bmp\\9t .wfb","bmp\\9t.wfb","bmp\\9t.wfb","bmp\\99.wfb"},{"bmp\\101.wfb","bmp\\102.wfb","bmp\\102.wfb","bmp\\104.wfb","bmp\\105.wfb"," bmp\\106.wfb","bmp\\108.wfb","bmp\\108.wfb","bmp\\109.wfb"}};char cursor[14][14]={0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,255,255,255,255,255,255,255,0,0,1,1,1,1,0,255,255,255,255,255,255,0,0,1,1,1,1,1,0,255,255,255,255,255,255,0,0,1,1,1,1,1,0,255,255,255,255,255,255,255,0,0,1,1,1,1,0,255,255,255,255,255,255,255,255,0,0,1,1,1,0,255,255,255,255,255,255,255,255,255,0,0,1,1,0,255,255,0,255,255,255,255,255,255,255,0,0,1,0,255,0,1,1,0,255,255,255,255,255,255,255,0,0,0,1,1,1,1,0,255,255,255,255,255,0,1,0,1,1,1,1,1,1,0,255,255,255,0,1,1,1,1,1,1,1,1,1,1,0,255,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1};struct pos{int x;int y;}position[10][9],redcurpos,redtemppos,redoldpos,blackcurpos,blacktemppos,blackold pos;/*----------------------------------------------------*/selectpage(register char page) /*换页函数*/{union REGS r;r.x.ax=0x4f05;r.x.bx=0;r.x.dx=page; /*选择页面*/int86(0x10,&r,&r);}unsigned char set_SVGA_mode(int vmode) /*设置SVGA屏幕模式*/{union REGS r;r.x.ax=0x4f02;r.x.bx=vmode;int86(0x10,&r,&r);return(r.h.ah);}unsigned int get_SVGA_mode() /*获取当前SVGA屏幕模式*/ {union REGS r;r.x.ax=0x4f03;int86(0x10,&r,&r);return(r.x.bx);}drawbmp(int start_x,int start_y,char filename[]){char buffer[640];int i,j,k,n,r,g,b,width,length;long position;FILE *fp;if((fp=fopen(filename,"rb"))==NULL){printf("Error! Can't open file!");getch();return;}fseek(fp,28,SEEK_SET);fread(&i,2,1,fp);if(i!=8) /*检查是否为256色位图*/{puts("Error!Can't find bitmap!");fclose(fp);getch();exit(0);}fseek(fp,18,SEEK_SET);fread(&width,4,1,fp);fread(&length,4,1,fp);if(firsttime){fseek(fp,54,SEEK_SET);for(i=0;i<256;i++) /*按照该图片的DAC色表设置色彩寄存器*/{b=fgetc(fp);g=fgetc(fp);r=fgetc(fp); /*获取R、G、B分量*/outportb(0x3c8,i);outportb(0x3c9,r>>2); /*右移是要转化为VGA的6位寄存器形式*/outportb(0x3c9,g>>2);outportb(0x3c9,b>>2);fgetc(fp);}}elsefseek(fp,300,SEEK_SET);k=(width%4)?(4-width%4):0; /*宽度修正值*/for(j=length-1+start_x;j>=start_x;j--){fread(buffer,width,1,fp);for(i=start_y,n=0;i<width+start_y;i++,n++){position=j*640l+i; /*计算要显示点的显存位置*/page_new=position/65536; /*计算显示页*/if(page_new!=page_old) /*当显示页不同时更换页面,提高一定的输出速度*/ {selectpage(page_new);page_old=page_new;}pokeb(0xa000,position%65536,buffer[n]); /*写到显存位置*/}fseek(fp,k,SEEK_CUR); /*每行绘制完后修正宽度*/}fclose(fp);}init(){savemode=get_SVGA_mode(); /*先保存原来的屏幕模式*/set_SVGA_mode(0x101); /*硬件无关性初始化屏幕为640*480 256色模式*/}end(){set_SVGA_mode(savemode); /*恢复屏幕*/ }/*----------------------------------------------------*/ initpos(){int i,j;for(i=0;i<10;i++)for (j=0;j<9;j++){position[i][j].x=35+i*39;position[i][j].y=43+j*40;}}initchessmap(){board[0][0]=BLACK_JU;board[0][1]=BLACK_MA;board[0][2]=BLACK_XIANG;board[0][3]=BLACK_SHI;board[0][4]=BLACK_JIANG;board[0][5]=BLACK_SHI;board[0][6]=BLACK_XIANG;board[0][7]=BLACK_MA;board[0][8]=BLACK_JU;board[2][1]=BLACK_PAO;board[2][7]=BLACK_PAO;board[3][0]=BLACK_BIN;board[3][2]=BLACK_BIN;board[3][4]=BLACK_BIN;board[3][6]=BLACK_BIN;board[3][8]=BLACK_BIN;board[9][0]=RED_JU;board[9][1]=RED_MA;board[9][2]=RED_XIANG;board[9][3]=RED_SHI;board[9][4]=RED_JIANG;board[9][5]=RED_SHI;board[9][6]=RED_XIANG;board[9][7]=RED_MA;board[9][8]=RED_JU;board[7][1]=RED_PAO;board[7][7]=RED_PAO;board[6][0]=RED_BIN;board[6][2]=RED_BIN;board[6][4]=RED_BIN;board[6][6]=RED_BIN;board[6][8]=RED_BIN;}initdrawchess(){int i,j;;for(i=0;i<10;i++)for(j=0;j<9;j++){if(board[i][j])drawbmp(position[i][j].x,position[i][j].y,chessfile[board[i][j]]);}}drawcursor(struct pos p){int i,j,n,m,x,y;long thisposition;x=position[p.x][p.y].x+20;y=position[p.x][p.y].y+25;for(j=13-1+x,m=13;j>=x;j--,m--){for(i=y,n=0;i<13+y;i++,n++){thisposition=j*640l+i; /*计算要显示点的显存位置*/page_new=thisposition/65536; /*计算显示页*/if(page_new!=page_old) /*当显示页不同时更换页面,提高一定的输出速度*/ {selectpage(page_new);page_old=page_new;}if(cursor[m][n]!=1)if(cursor[m][n]==0)pokeb(0xa000,thisposition%65536,0);elseif(turn==RED)pokeb(0xa000,thisposition%65536,153);elsepokeb(0xa000,thisposition%65536,255);}}}drawselecursor(struct pos p){int i,j,n,m,x,y;long thisposition;x=position[p.x][p.y].x+20;y=position[p.x][p.y].y+25;for(j=13-1+x,m=13;j>=x;j--,m--){for(i=y,n=0;i<13+y;i++,n++){thisposition=j*640l+i; /*计算要显示点的显存位置*/page_new=thisposition/65536; /*计算显示页*/if(page_new!=page_old) /*当显示页不同时更换页面,提高一定的输出速度*/ {selectpage(page_new);page_old=page_new;}if(cursor[m][n]!=1)pokeb(0xa000,thisposition%65536,0);}}}/*----------------------------------------------------*/int getkey(){int press;while(bioskey(1) == 0);press=bioskey(0);press=press&0xff00;return(press);}/*--------------------红方操作--------------------*/int redcanselect(){int x,y;x=redcurpos.x;y=redcurpos.y;if(board[x][y]>=RED_JU&&board[x][y]<=RED_BIN)return 1;elsereturn 0;}int redcanmove(){int i,j,min,max,oldx,oldy,x,y;oldx=redoldpos.x;oldy=redoldpos.y;x=redcurpos.x;y=redcurpos.y;/*case1 目标位置是否是自己人*/if(board[x][y]>=RED_JU&&board[x][y]<=RED_BIN)return 0;/* 军、马、炮、相、士、将、卒的走法正确性的判断*/ switch(board[oldx][oldy]){case RED_BIN: /*完成*/if(oldx>=5){ if(y!=oldy||(oldx-x)!=1) return 0;}else{ if(x==(oldx-1)&&y==oldy) return 1;elseif(x==oldx&&y==(oldy+1)) return 1;elseif(x==oldx&&y==(oldy-1)) return 1;elsereturn 0;}break;case RED_JIANG: /*完成*/if(x!=oldx&&y!=oldy) return 0;if(x!=oldx)if((x-oldx)>1||(oldx-x)>1) return 0;else if(x<7) return 0;else if(y!=oldy)if((y-oldy)>1||(oldy-y)>1) return 0;else if(y<3||y>5) return 0;break;case RED_JU: /*完成*/if(x!=oldx&&y!=oldy) return 0;else if(x!=oldx){ min=(x>oldx)?oldx:x;max=(x>oldx)?x:oldx;for(i=min+1;i<max;i++)if(board[i][y]!=0) return 0;}else if(y!=oldy){ min=(y>oldy)?oldy:y;max=(y>oldy)?y:oldy;for(i=min+1;i<max;i++)if(board[x][i]!=0) return 0;}break;case RED_MA: /*完成*/if((x-oldx)==2&&((y-oldy)==1||(oldy-y)==1)) {if(board[oldx+1][oldy]!=0) return 0;}elseif((oldx-x)==2&&((y-oldy)==1||(oldy-y)==1)) {if(board[oldx-1][oldy]!=0) return 0;}elseif((y-oldy)==2&&((x-oldx)==1||(oldx-x)==1)) {if(board[oldx][oldy+1]!=0) return 0;}elseif((oldy-y)==2&&((x-oldx)==1||(oldx-x)==1)) {if(board[oldx][oldy-1]!=0) return 0;}elsereturn 0;break;case RED_PAO: /*完成*/ if(x!=oldx&&y!=oldy) return 0;if(board[x][y]==0){if(x!=oldx){ min=(x>oldx)?oldx:x;max=(x>oldx)?x:oldx;for(i=min+1;i<max;i++)if(board[i][y]!=0) return 0;}else if(y!=oldy){ min=(y>oldy)?oldy:y;max=(y>oldy)?y:oldy;for(i=min+1;i<max;i++)if(board[x][i]!=0) return 0;}}else{if(x!=oldx){ min=(x>oldx)?oldx:x;max=(x>oldx)?x:oldx;for(i=min+1,j=0;i<max;i++)if(board[i][y]!=0) j++;if(j!=1) return 0;}else if(y!=oldy){ min=(y>oldy)?oldy:y;max=(y>oldy)?y:oldy;for(i=min+1,j=0;i<max;i++)if(board[x][i]!=0) j++;if(j!=1) return 0;}}break;case RED_SHI: /*完成*/ if(oldx==9||oldx==7){if(x!=8||y!=4) return 0;}else if(oldx==8){if(x==9&&y==3) return 1;elseif(x==9&&y==5) return 1;elseif(x==7&&y==3) return 1;elseif(x==7&&y==5) return 1;else return 0;}else return 0;break;case RED_XIANG: /*完成*/if(x<5) return 0;if(x!=oldx&&y!=oldy){if((x-oldx)==2&&(y-oldy)==2){i=oldx+1;j=oldy+1;}else if((x-oldx)==2&&(oldy-y)==2){i=oldx+1;j=oldy-1;}else if((oldx-x)==2&&(y-oldy)==2){i=oldx-1;j=oldy+1;}else if((oldx-x)==2&&(oldy-y)==2){i=oldx-1;j=oldy-1;}else return 0;if(board[i][j]!=0) return 0;}else return 0;break;}return 1;}redup(){int x,y,n;if(redcurpos.x>0){redcurpos.x--;x=position[redtemppos.x][redtemppos.y].x;y=position[redtemppos.x][redtemppos.y].y;if(board[redtemppos.x][redtemppos.y]==0)drawbmp(x,y,boardfile[redtemppos.x][redtemppos.y]);elseif(!(redtemppos.x==redoldpos.x&&redtemppos.y==redoldpos.y&&redstate==MOVE )){n=board[redtemppos.x][redtemppos.y];drawbmp(x,y,chessfile[n]);}if(redtemppos.x==redoldpos.x&&redtemppos.y==redoldpos.y&&redstate==MOVE) drawselecursor(redoldpos);drawcursor(redcurpos);redtemppos.x=redcurpos.x;redtemppos.y=redcurpos.y;}}reddown(){int x,y,n;if(redcurpos.x<9){redcurpos.x++;x=position[redtemppos.x][redtemppos.y].x;y=position[redtemppos.x][redtemppos.y].y;if(board[redtemppos.x][redtemppos.y]==0)drawbmp(x,y,boardfile[redtemppos.x][redtemppos.y]);elseif(!(redtemppos.x==redoldpos.x&&redtemppos.y==redoldpos.y&&redstate==MOVE )){n=board[redtemppos.x][redtemppos.y];drawbmp(x,y,chessfile[n]);}if(redtemppos.x==redoldpos.x&&redtemppos.y==redoldpos.y&&redstate==MOVE) drawselecursor(redoldpos);drawcursor(redcurpos);redtemppos.x=redcurpos.x;redtemppos.y=redcurpos.y;}}redleft(){int x,y,n;if(redcurpos.y>0){redcurpos.y--;x=position[redtemppos.x][redtemppos.y].x;y=position[redtemppos.x][redtemppos.y].y;if(board[redtemppos.x][redtemppos.y]==0)drawbmp(x,y,boardfile[redtemppos.x][redtemppos.y]);elseif(!(redtemppos.x==redoldpos.x&&redtemppos.y==redoldpos.y&&redstate==MOVE )){n=board[redtemppos.x][redtemppos.y];drawbmp(x,y,chessfile[n]);}if(redtemppos.x==redoldpos.x&&redtemppos.y==redoldpos.y&&redstate==MOVE) drawselecursor(redoldpos);drawcursor(redcurpos);redtemppos.x=redcurpos.x;redtemppos.y=redcurpos.y;}}redright(){int x,y,n;if(redcurpos.y<8){redcurpos.y++;x=position[redtemppos.x][redtemppos.y].x;y=position[redtemppos.x][redtemppos.y].y;if(board[redtemppos.x][redtemppos.y]==0)drawbmp(x,y,boardfile[redtemppos.x][redtemppos.y]);elseif(!(redtemppos.x==redoldpos.x&&redtemppos.y==redoldpos.y&&redstate==MOVE )){n=board[redtemppos.x][redtemppos.y];drawbmp(x,y,chessfile[n]);}if(redtemppos.x==redoldpos.x&&redtemppos.y==redoldpos.y&&redstate==MOVE) drawselecursor(redoldpos);drawcursor(redcurpos);redtemppos.x=redcurpos.x;redtemppos.y=redcurpos.y;}}reddo(){int i,j,x,y,n;if(redstate==SELECT&&redcanselect()){if(board[redcurpos.x][redcurpos.y]<=RED&&board[redcurpos.x][redcurpos.y]>0) {redstate=MOVE;drawselecursor(redcurpos);redoldpos.x=redcurpos.x;redoldpos.y=redcurpos.y;}}else if(redstate==MOVE&&redcanmove()){x=position[redoldpos.x][redoldpos.y].x;y=position[redoldpos.x][redoldpos.y].y;drawbmp(x,y,boardfile[redoldpos.x][redoldpos.y]);x=position[redcurpos.x][redcurpos.y].x;y=position[redcurpos.x][redcurpos.y].y;n=board[redoldpos.x][redoldpos.y];drawbmp(x,y,chessfile[n]);if(board[redcurpos.x][redcurpos.y]==BLACK_JIANG){winner=RED;finish=1;return;}board[redcurpos.x][redcurpos.y]=n;board[redoldpos.x][redoldpos.y]=0;for(i=0;i<=2;i++)for(j=3;j<=5;j++)if(board[i][j]==BLACK_JIANG){x=i;y=j;}for(i=x+1,j=y,n=0;i<=9;i++){if(board[i][j]==RED_JIANG&&n==0){winner=BLACK;finish=1;break;}else if(board[i][j]!=0) n++;}turn=BLACK;blackstate=SELECT;drawcursor(blackcurpos);drawbmp(30,438,"bmp\\bzq.wfb"); /*转交控制权给黑方*/ }}redundo(){int x,y,n;if(redstate==MOVE){x=position[redoldpos.x][redoldpos.y].x;y=position[redoldpos.x][redoldpos.y].y;n=board[redoldpos.x][redoldpos.y];drawbmp(x,y,chessfile[n]);redoldpos.x=redcurpos.x;redoldpos.y=redcurpos.y;drawcursor(redcurpos);redstate=SELECT;}}/*--------------------黑方操作----------------------*/int blackcanselect(){int x,y;x=blackcurpos.x;y=blackcurpos.y;if(board[x][y]>=BLACK_JU&&board[x][y]<=BLACK_BIN)return 1;elsereturn 0;}int blackcanmove(){int i,j,min,max,oldx,oldy,x,y;oldx=blackoldpos.x;oldy=blackoldpos.y;x=blackcurpos.x;y=blackcurpos.y;/*case1 目标位置是否是自己人*/if(board[x][y]>=BLACK_JU&&board[x][y]<=BLACK_BIN) return 0;/* 军、马、炮、相、士、将、卒的走法正确性的判断*/ switch(board[oldx][oldy]){case BLACK_JU: /*完成*/if(x!=oldx&&y!=oldy) return 0;else if(x!=oldx){ min=(x>oldx)?oldx:x;max=(x>oldx)?x:oldx;for(i=min+1;i<max;i++)if(board[i][y]!=0) return 0;}else if(y!=oldy){ min=(y>oldy)?oldy:y;max=(y>oldy)?y:oldy;for(i=min+1;i<max;i++)if(board[x][i]!=0) return 0;}break;case BLACK_MA: /*完成*/if((x-oldx)==2&&((y-oldy)==1||(oldy-y)==1)){if(board[oldx+1][oldy]!=0) return 0;}elseif((oldx-x)==2&&((y-oldy)==1||(oldy-y)==1)){if(board[oldx-1][oldy]!=0) return 0;}elseif((y-oldy)==2&&((x-oldx)==1||(oldx-x)==1)){if(board[oldx][oldy+1]!=0) return 0;}elseif((oldy-y)==2&&((x-oldx)==1||(oldx-x)==1)){if(board[oldx][oldy-1]!=0) return 0;}elsereturn 0;break;case BLACK_PAO: /*完成*/if(x!=oldx&&y!=oldy) return 0;if(board[x][y]==0){if(x!=oldx){ min=(x>oldx)?oldx:x;max=(x>oldx)?x:oldx;for(i=min+1;i<max;i++)if(board[i][y]!=0) return 0;}else if(y!=oldy){ min=(y>oldy)?oldy:y;max=(y>oldy)?y:oldy;for(i=min+1;i<max;i++)if(board[x][i]!=0) return 0;}}else{j=0;if(x!=oldx){ min=(x>oldx)?oldx:x;max=(x>oldx)?x:oldx;for(i=min+1;i<max;i++)if(board[i][y]!=0) j++;if(j!=1) return 0;}else if(y!=oldy){ min=(y>oldy)?oldy:y;max=(y>oldy)?y:oldy;for(i=min+1;i<max;i++)if(board[x][i]!=0) j++;if(j!=1) return 0;}}break;case BLACK_XIANG:if(x>4) return 0;if(x!=oldx&&y!=oldy){if((x-oldx)==2&&(y-oldy)==2){i=oldx+1;j=oldy+1;}else if((x-oldx)==2&&(oldy-y)==2){i=oldx+1;j=oldy-1;}else if((oldx-x)==2&&(y-oldy)==2) {i=oldx-1;j=oldy+1;}else if((oldx-x)==2&&(oldy-y)==2) {i=oldx-1;j=oldy-1;}else return 0;if(board[i][j]!=0) return 0;}else return 0;break;case BLACK_SHI:if(oldx==0||oldx==2){if(x!=1||y!=4) return 0;}else if(oldx==1){if(x==0&&y==3) return 1;elseif(x==0&&y==5) return 1;elseif(x==2&&y==3) return 1;elseif(x==2&&y==5) return 1;else return 0;}else return 0;break;case BLACK_JIANG:if(x!=oldx&&y!=oldy) return 0;if(x!=oldx)if((x-oldx)>1||(oldx-x)>1) return 0;else if(x>2) return 0;else if(y!=oldy)if((y-oldy)>1||(oldy-y)>1) return 0;else if(y<3||y>5) return 0;break;case BLACK_BIN:if(oldx<=4){ if(y!=oldy||(x-oldx)!=1) return 0;}else{ if(x==(oldx+1)&&y==oldy) return 1; elseif(x==oldx&&y==(oldy+1)) return 1; elseif(x==oldx&&y==(oldy-1)) return 1;elsereturn 0;}break;}return 1;}blackup(){int x,y,n;if(blackcurpos.x>0){blackcurpos.x--;x=position[blacktemppos.x][blacktemppos.y].x;y=position[blacktemppos.x][blacktemppos.y].y;if(board[blacktemppos.x][blacktemppos.y]==0)drawbmp(x,y,boardfile[blacktemppos.x][blacktemppos.y]);elseif(!(blacktemppos.x==blackoldpos.x&&blacktemppos.y==blackoldpos.y&&blackstat e==MOVE)){n=board[blacktemppos.x][blacktemppos.y];drawbmp(x,y,chessfile[n]);}if(blacktemppos.x==blackoldpos.x&&blacktemppos.y==blackoldpos.y&&blackstate ==MOVE)drawselecursor(blackoldpos);drawcursor(blackcurpos);blacktemppos.x=blackcurpos.x;blacktemppos.y=blackcurpos.y;}}blackdown(){int x,y,n;if(blackcurpos.x<9){blackcurpos.x++;x=position[blacktemppos.x][blacktemppos.y].x;y=position[blacktemppos.x][blacktemppos.y].y;if(board[blacktemppos.x][blacktemppos.y]==0)drawbmp(x,y,boardfile[blacktemppos.x][blacktemppos.y]);elseif(!(blacktemppos.x==blackoldpos.x&&blacktemppos.y==blackoldpos.y&&blackstat e==MOVE)){n=board[blacktemppos.x][blacktemppos.y];drawbmp(x,y,chessfile[n]);}if(blacktemppos.x==blackoldpos.x&&blacktemppos.y==blackoldpos.y&&blackstate ==MOVE)drawselecursor(blackoldpos);drawcursor(blackcurpos);blacktemppos.x=blackcurpos.x;blacktemppos.y=blackcurpos.y;}}blackleft(){int x,y,n;if(blackcurpos.y>0){blackcurpos.y--;x=position[blacktemppos.x][blacktemppos.y].x;y=position[blacktemppos.x][blacktemppos.y].y;if(board[blacktemppos.x][blacktemppos.y]==0)drawbmp(x,y,boardfile[blacktemppos.x][blacktemppos.y]);elseif(!(blacktemppos.x==blackoldpos.x&&blacktemppos.y==blackoldpos.y&&blackstat e==MOVE)){n=board[blacktemppos.x][blacktemppos.y];drawbmp(x,y,chessfile[n]);}if(blacktemppos.x==blackoldpos.x&&blacktemppos.y==blackoldpos.y&&blackstate ==MOVE)drawselecursor(blackoldpos);drawcursor(blackcurpos);blacktemppos.x=blackcurpos.x;blacktemppos.y=blackcurpos.y;}blackright(){int x,y,n;if(blackcurpos.y<8){blackcurpos.y++;x=position[blacktemppos.x][blacktemppos.y].x;y=position[blacktemppos.x][blacktemppos.y].y;if(board[blacktemppos.x][blacktemppos.y]==0)drawbmp(x,y,boardfile[blacktemppos.x][blacktemppos.y]);elseif(!(blacktemppos.x==blackoldpos.x&&blacktemppos.y==blackoldpos.y&&blackstat e==MOVE)){n=board[blacktemppos.x][blacktemppos.y];drawbmp(x,y,chessfile[n]);}if(blacktemppos.x==blackoldpos.x&&blacktemppos.y==blackoldpos.y&&blackstate ==MOVE)drawselecursor(blackoldpos);drawcursor(blackcurpos);blacktemppos.x=blackcurpos.x;blacktemppos.y=blackcurpos.y;}}blackdo(){int i,j,x,y,n;if(blackstate==SELECT&&blackcanselect()){if(board[blackcurpos.x][blackcurpos.y]<=BLACK&&board[blackcurpos.x][blackcurp os.y]>0){blackstate=MOVE;drawselecursor(blackcurpos);blackoldpos.x=blackcurpos.x;blackoldpos.y=blackcurpos.y;}else if(blackstate==MOVE&&blackcanmove()){x=position[blackoldpos.x][blackoldpos.y].x;y=position[blackoldpos.x][blackoldpos.y].y;drawbmp(x,y,boardfile[blackoldpos.x][blackoldpos.y]);x=position[blackcurpos.x][blackcurpos.y].x;y=position[blackcurpos.x][blackcurpos.y].y;n=board[blackoldpos.x][blackoldpos.y];drawbmp(x,y,chessfile[n]);if(board[blackcurpos.x][blackcurpos.y]==RED_JIANG){winner=BLACK;finish=1;return;}board[blackcurpos.x][blackcurpos.y]=n;board[blackoldpos.x][blackoldpos.y]=0;for(i=0;i<=2;i++)for(j=3;j<=5;j++)if(board[i][j]==BLACK_JIANG){x=i;y=j;}for(i=x+1,j=y,n=0;i<=9;i++){if(board[i][j]==RED_JIANG&&n==0){winner=RED;finish=1;break;}else if(board[i][j]!=0) n++;}turn=RED;redstate=SELECT;drawcursor(redcurpos);drawbmp(30,438,"bmp\\rzq.wfb"); /*转交控制权给红方*/ }}blackundo(){int x,y,n;if(blackstate==MOVE){x=position[blackoldpos.x][blackoldpos.y].x; y=position[blackoldpos.x][blackoldpos.y].y; n=board[blackoldpos.x][blackoldpos.y];drawbmp(x,y,chessfile[n]);blackoldpos.x=blackcurpos.x;blackoldpos.y=blackcurpos.y;drawcursor(blackcurpos);blackstate=SELECT;}}/*----------------------------------------------------*/ start(){drawcursor(blackcurpos);drawbmp(30,438,"bmp\\bzq.wfb");while(!finish){key=getkey();switch(key){case RED_UP:if(turn==RED)redup();break;case RED_DOWN:if(turn==RED)reddown();break;case RED_LEFT:if(turn==RED)redleft();break;case RED_RIGHT:if(turn==RED)redright();break;case RED_DO:if(turn==RED)reddo();break;case RED_UNDO:if(turn==RED)redundo();break;case BLACK_UP:if(turn==BLACK)blackup();break;case BLACK_DOWN:if(turn==BLACK)blackdown();break;case BLACK_LEFT:if(turn==BLACK)blackleft();break;case BLACK_RIGHT:if(turn==BLACK)blackright();break;case BLACK_DO:if(turn==BLACK)blackdo();break;case BLACK_UNDO:if(turn==BLACK)blackundo();break;case ESCAPE: finish=1;break; }}}main(){init();initpos();initchessmap();drawbmp(0,0,"bmp\\board.wfb"); initdrawchess();/*初始化光标位置*/redcurpos.x=redoldpos.x=redtemppos.x=9;redcurpos.y=redoldpos.y=redtemppos.y=8;blackcurpos.x=blackoldpos.x=blacktemppos.x=0; blackcurpos.y=blackoldpos.y=blacktemppos.y=0; /*开始*/start();if(winner==RED)drawbmp(200,200,"bmp\\redwin.wfb");else if(winner==BLACK)drawbmp(200,200,"bmp\\blackwin.wfb");elsedrawbmp(200,200,"bmp\\exit.wfb");getch();end();}。

c++制作的小游戏——黑白棋

c++制作的小游戏——黑白棋
for(x1 = x - 1, y1 = y - 1; x1 >= 0 && y1 >= 0 && map[x1][y1]; x1--, y1--) //左上方
{
if(map[x1][y1]== b)
sign = true;
else
{
if(sign)
{
int black, white; //双方的棋子数
char today; //当前轮到谁走
/**********************************定义函数*****************************/
void load(void) //加载图片
{
loadimage(&img[0], "图片\\黑空.jpg");
loadimage(&img[1], "图片\\白空.jpg");
loadimage(&img[2], "图片\\黑子黑空.jpg");
loadimage(&img[3], "图片\\黑子白空.jpg");
loadimage(&img[4], "图片\\白子黑空.jpg");
loadimage(&img[5], "图片\\白子白空.jpg");
}
void print(void) //画棋盘
{
int x, y;
black = white = 0;
for(x = 0; x < 8; x++)
for(y = 0; y < 8; y++)

c语言编译的简单黑白棋源代码

c语言编译的简单黑白棋源代码

#include <stdio.h>#include <ctype.h>#define SIZE 8void display(char board[][SIZE]);int valid_moves(char board[][SIZE],int moves[][SIZE],char player);void make_move(char board[][SIZE],int row,int col,char player);void computer_move(char board[][SIZE],int moves[][SIZE],char player);int get_score(char board[][SIZE],char player);int best_move(char board[][SIZE],int moves[][SIZE],char player);int main(){char board[SIZE][SIZE]={0};int moves[SIZE][SIZE]={0};int row=0;int col=0;int no_of_games=0;int no_of_moves=0;int invalid_moves=0;int comp_score=0;int user_score=0;char y=0;char x=0;char again=0;int player=0;printf("\nREVERSI\n\n");printf("You can go first on the first game,then we will take truns.\n"); printf(" You will be white - (0)\n I will be black - (@).\n");printf("Select a square for your move by typing a digit for the row\n" "and a letter for the column with no spaces between.\n");printf("\nGood luck! press Enter to start.\n");scanf("%c",&again);do{player=++no_of_games%2;no_of_moves=4;for(row=0;row<SIZE;row++)for(col=0;col<SIZE;col++)board[row][col]=' ';board[SIZE/2-1][SIZE/2-1]=board[SIZE/2][SIZE/2]='0';board[SIZE/2-1][SIZE/2]=board[SIZE/2][SIZE/2-1]='@';do{display(board);if(player++%2){if(valid_moves(board,moves,'0')){for(;;){fflush(stdin);printf("Please enter your move (row column): ");scanf("%d%c",&x,&y);y=tolower(y)-'a';x--;if(x>=0&&y>=0&&x<SIZE&&y<SIZE&&moves[x][y]){make_move(board,x,y,'0');no_of_moves++;break;}elseprintf("Not a valid move,try again.\n");}}elseif(++invalid_moves<2){fflush(stdin);printf("\nYou have to pass,press return");scanf("%c",&again);}elseprintf("\nNeither of us can go, so the game is over.\n"); }else{if(valid_moves(board,moves,'@')){invalid_moves=0;computer_move(board,moves,'@');no_of_moves++;}else{if(++invalid_moves<2)printf("\nI have to pass, your go\n");elseprintf("\nNeither of us can go, so the game is over.\n"); }}}while(no_of_moves<SIZE*SIZE&&invalid_moves<2);display(board);comp_score=user_score=0;for(row=0;row<SIZE;row++)for(col=0;col<SIZE;col++){comp_score+=board[row][col]=='@';user_score+=board[row][col]=='0';}printf("The final score is:\n");printf("Computer %d\n User %d\n\n",comp_score,user_score);fflush(stdin);printf("Do you want to play again (y/n): ");scanf("%c",&again);}while(tolower(again)=='y');printf("\nGoodbye\n");}void display(char board[][SIZE]){int row=0;int col=0;char col_label='a';printf("\n ");for(col=0;col<SIZE;col++)printf(" %c",col_label+col);printf("\n");for(row=0;row<SIZE;row++){printf(" +");for(col=0;col<SIZE;col++)printf("---+");printf("\n%2d|",row+1);for(col=0;col<SIZE;col++)printf(" %c |",board[row][col]);printf("\n");}printf(" +");for(col=0;col<SIZE;col++)printf("---+");printf("\n");}int valid_moves(char board[][SIZE],int moves[][SIZE],char player) {int rowdelta=0;int coldelta=0;int row=0;int col=0;int x=0;int y=0;int no_of_moves=0;char opponent=(player=='0')?'@':'0';for(row=0;row<SIZE;row++)for(col=0;col<SIZE;col++)moves[row][col]=0;for(row=0;row<SIZE;row++)for(col=0;col<SIZE;col++){if(board[row][col]!=' ')continue;for(rowdelta=-1;rowdelta<=1;rowdelta++)for(coldelta=-1;coldelta<=1;coldelta++){if(row+rowdelta<0||row+rowdelta>=SIZE||col+coldelta<0||col+coldelta>=SIZE||(rowdelta==0&&coldelta==0))continue;if(board[row+rowdelta][col+coldelta]==opponent){x=row+rowdelta;y=col+coldelta;for(;;){x+=rowdelta;y+=coldelta;if(x<0||x>=SIZE||y<0||y>=SIZE)break;if(board[x][y]==' ')break;if(board[x][y]==player){moves[row][col]=1;no_of_moves++;break;}}}}}return no_of_moves;}void make_move(char board[][SIZE],int row,int col,char player) {int rowdelta=0;int coldelta=0;int x=0;int y=0;char opponent=(player=='0')?'@':'0';board[row][col]=player;for(rowdelta=-1;rowdelta<=1;rowdelta++)for(coldelta=-1;coldelta<=1;coldelta++){if(row+rowdelta<0||row+rowdelta>=SIZE||col+coldelta<0||col+coldelta>=SIZE||(rowdelta==0&&coldelta==0))continue;if(board[row+rowdelta][col+coldelta]==opponent){x=row+rowdelta;y=col+coldelta;for(;;){x+=rowdelta;y+=coldelta;if(x<0||x>=SIZE||y<0||y>=SIZE)break;if(board[x][y]==' ')break;if(board[x][y]==player){while(board[x-=rowdelta][y-=coldelta]==opponent) board[x][y]=player;break;}}}}}int get_score(char board[][SIZE],char player){int score=0;int row=0;int col=0;char opponent=player=='0'?'@':'0';for(row=0;row<SIZE;row++)for(col=0;col<SIZE;col++){score-=board[row][col]==opponent;score+=board[row][col]==player;}return score;}int best_move(char board[][SIZE],int moves[][SIZE],char player){int row=0;int col=0;int i=0;int j=0;char opponent=player=='0'?'@':'0';char new_board[SIZE][SIZE]={0};int score=0;int new_score=0;for(row=0;row<SIZE;row++)for(col=0;col<SIZE;col++){if(!moves[row][col])continue;for(i=0;i<SIZE;i++)for(j=0;j<SIZE;j++)new_board[i][j]=board[i][j];make_move(new_board,row,col,player);new_score=get_score(new_board,player);if(score<new_score)score=new_score;}return score;}void computer_move(char board[][SIZE],int moves[][SIZE],char player) {int row=0;int col=0;int best_row=0;int best_col=0;int i=0;int j=0;int new_score=0;int score=100;char temp_board[SIZE][SIZE];int temp_moves[SIZE][SIZE];char opponent=player=='0'?'@':'0';for(row=0;row<SIZE;row++)for(col=0;col<SIZE;col++){if(moves[row][col]==0)continue;for(i=0;i<SIZE;i++)for(j=0;j<SIZE;j++)temp_board[i][j]=board[i][j];make_move(temp_board,row,col,player);valid_moves(temp_board,temp_moves,opponent);new_score=best_move(temp_board,temp_moves,opponent);if(new_score<score){score=new_score;best_row=row;best_col=col;}}make_move(board,best_row,best_col,player);}。

五子棋c语言版

五子棋c语言版

#include<stdio.h>#include<string.h>#include<time.h>#include<stdlib.h>#define N 19int i,j,k,size=N;int isBlack=1;//当前是黑方下子 isBlack=1 若为白方下子 isBlack=0char state[N][N];char x,y,temp[10];char c; //用来存放显示黑白子的变量void printState();void startGame(){//printf("\n潇洒菠菜提示:此功能待开发...\n");//当前初始化面板。

for(i=0;i<size;i++){for(j=0;j<size;j++){state[i][j]='*';}}printState();while(1){printf("\n\t请%s方下子:",isBlack?"黑":"白");fflush(stdin);scanf("%s",temp);if(!strcmp(strupr(temp),"OUT")) //如果在下的过程中输入OUT 的话就返回主菜单{system("cls");return;}if(!strcmp(temp,"BACK")) //悔棋... BACK{i=x-'A'; //这里i和j承担过循环控制变量!需要重新初始化j=y-'A';state[i][j]='*';printState();printf("\t 观棋不语真君子,落子不悔大丈夫!\n");isBlack=!isBlack;continue;}if(!strcmp(temp,"LOSE")) //认输... LOSE{printf("\n\t潇洒菠菜提示:%s方认输,%s方胜!\n\n",isBlack?"黑":"白",isBlack?"白":"黑");return;}x=temp[0]; //取前两个字符做处理。

C语言编写象棋软件源代码

C语言编写象棋软件源代码
"bmp\\rjiang.wfb","bmp\\rpao.wfb","bmp\\rbin.wfb",
"bmp\\bju.wfb","bmp\\bma.wfb","bmp\\bxiang.wfb","bmp\\bshi.wfb",
"bmp\\bjiang.wfb","bmp\\bpao.wfb","bmp\\bbin.wfb"
};
char *boardfile[10][9]={
{"bmp\\11.wfb","bmp\\1t.wfb","bmp\\1t.wfb","bmp\\14.wfb","bmp\\15.wfb","bmp\\16.wfb","bmp\\1t.wfb","bmp\\1t.wfb","bmp\\19.wfb"},
#define RED_DO 0x3900
#define RED_UNDO 0x1000
#define BLACK_UP 0x4800
#define BLACK_DOWN 0x5000
#define BLACK_LEFT 0x4b00
#define BLACK_RIGHT 0x4d00
#define BLACK_DO 0x1c00
{"bmp\\81.wfb","bmp\\8a.wfb","bmp\\8t.wfb","bmp\\84.wfb","bmp\\85.wfb","bmp\\86.wfb","bmp\\8t.wfb","bmp\\8a.wfb","bmp\\89.wfb"},

用c++实现黑白棋

用c++实现黑白棋

用c++实现黑白棋黑白棋规则介绍黑白棋是由黑方和白方两人进行的益智游戏。

棋盘为N×N方格,黑白棋总共使用N2个棋子,每个棋子分正反两面,分别是黑色和白色。

轮到一方下棋时,必须把棋下在与对方棋子相邻的空位上,要求所下的棋子和原有的已方棋子夹住对方的至少一个棋子(横竖斜夹均可),然后把被夹住的子变成己方的颜色(也叫吃子)。

下棋过程中,任何棋子既不会从棋盘上拿走,也不会从一个格子移到另一个格子,吃子时,不会发生连锁反应,吃进的棋子不能再夹吃其他的子。

当双方都无棋可下,或者方格全部占满后,棋局结束,子多的一方为胜方。

黑白棋人工智能的实现我们这里取棋盘大小为10×10个方格,用数组int state[10][10]来表示棋盘的状态,其中0表示方格为空,-1表示用黑方的棋,1表示白方的棋。

在10×10的棋盘上,除了那些已经有子的地方不能走子外,那些不能吃子的点也不能走。

如何判断某个点(x, y)能不能走子呢?通过分析黑白棋的规则我们知道,在这一个方格上的八个方向的任何一个方向上只要满足:在这个方向与之相邻的有连续若干个对方的棋子,接着有一个己方的子,我们就可以肯定这一点能够走子。

所以我定义了一个数组int dirstate[8](数组从右逆时针开始,如dirstate[0]表示右,dirstate[1]表示右上,以此类推)来表示个方向的状态,值1表示在这个方向上可以吃掉对方的子,值0则表示不能,同时定义一个函数movedir(int x,int y,int mover)来判断各方向的状态,函数movedir的具体实现见源代码,这里以右方向为例说明,其他各个方向类似,右方向的判断可以用以下语句实现:int tx=x+1,ty=y,step=0;//tx,ty分别用来表示右方向各点在数组中的索引dirstate[0]=0;//初始化为不能吃子while(1){if(tx>9) break;//处于边界,退出循环,该方向不能吃子if(state[ty][tx]==0) break; //空子,退出循环,该方向不能吃子if(state[ty][tx]!=mover) step++;//(tx,ty)所在的方格上的棋不一样,step加1,有连//续step个对方的棋子与(x,y)上的棋相邻else {if(step>0) dirstate[0]=1;break;}// (tx,ty)所在的方格上的棋一样,同时在(tx,ty)//和(x,y)之间如果有连续step个对方的棋子,则、//表示该方向上可以吃子,修改dirstate[0]状态。

黑白棋程序段

黑白棋程序段

黑白棋程序段#include <iostream>using namespace std;int const MAX=10000;enum Color{WHITE=-1,BLANK,BLACK //是否能落子//黑子};class Choice{public:int posX;int posY;int score;};class Chessman{public:enum Color color;unsigned stable; /* 棋子的稳定性(0~8),若棋子为BLANK则表示该位置落子后可翻过的棋子个数. */}; //即下此位置后对方的棋变为自己的棋子的数目class Chessboard //棋盘{public:Chessman cell[8][8]; //定义棋盘中有8*8个格子unsigned whiteNum; //白棋数目unsigned blackNum; //黑棋数void initChessboard(Chessboard *board);void clone( Chessboard *boardDest,const Chessboard *boardSource);void view( Chessboard *board);int judge( Chessboard *board,enum Color player);int putChess( Chessboard *board,Choice *choice,enum Color player);void setStable( Chessboard *board);int evaluate(Chessboard *board,enum Color player);};void Chessboard::initChessboard(Chessboard *board) //初始化棋盘{ //声明一个Chessboard结构体board int i,j;board->whiteNum=2;board->blackNum=2;for(i=0;i<8;i++){for(j=0;j<8;j++){board->cell[i][j].color=BLANK;board->cell[i][j].stable=0;}}board->cell[3][3].color=board->cell[4][4].color=BLACK;board->cell[3][4].color=board->cell[4][3].color=WHITE;}// 复制棋盘.void Chessboard::clone( Chessboard *boardDest,const Chessboard *boardSource){int i,j;boardDest->whiteNum=boardSource->whiteNum;boardDest->blackNum=boardSource->blackNum;for(i=0;i<8;i++){for(j=0;j<8;j++){boardDest->cell[i][j].color=boardSource->cell[i][j].color;boardDest->cell[i][j].stable=boardSource->cell[i][j].stable;}}}//显示棋盘.void Chessboard::view( Chessboard *board){int i,j;cout<<"\n---";for(i=0;i<8;i++){cout<<"---"<<i+1;}cout<<"\n ────────────────\n";for(i=0;i<8;i++){cout<<i+1<<"--│";for(j=0;j<8;j++){switch(board->cell[i][j].color){case BLACK:cout<<"○│";break;case WHITE:cout<<"●│";break;case BLANK:if(board->cell[i][j].stable){cout<<" +│";}else{cout<<" │";}break;default: /* 棋子颜色错误*/cout<<"* │";}}cout<<"\n ────────────────\n";}cout<<"白棋(●)个数为:"<<board->whiteNum<<" ";cout<<"黑棋(○)个数为:"<<board->blackNum<<endl<<endl<<endl;}// 计算可落子的位置个数,及该位置落子后翻过的棋子的个数(board->cell[i][j].stable)int Chessboard::judge( Chessboard *board,enum Color player){int i,j;unsigned num=0;for(i=0;i<8;i++){for(j=0;j<8;j++){if(board->cell[i][j].color==BLANK){int x,y;board->cell[i][j].stable=0;for(x=-1;x<=1;x++){for(y=-1;y<=1;y++){if(x||y) /* 8个方向*/{int i2,j2;unsigned num2=0;for(i2=i+x,j2=j+y;i2>=0 && i2<=7 && j2>=0 && j2<=7;i2+=x,j2+=y){if(board->cell[i2][j2].color==(enum Color)-player){num2++;}else if(board->cell[i2][j2].color==player){board->cell[i][j].stable+=player*num2;break;}else if(board->cell[i2][j2].color==BLANK){break;}}}}}if(board->cell[i][j].stable){num++;}}}}return num;}//落子,翻子.int Chessboard::putChess( Chessboard *board,Choice *choice,enum Color player){int i=choice->posX,j=choice->posY;int x,y;if(board->cell[i][j].color!=BLANK || board->cell[i][j].stable==0 || player==BLANK) {return -1;}board->cell[i][j].color=player;board->cell[i][j].stable=0;if(player==WHITE){board->whiteNum++;}else if(player==BLACK){board->blackNum++;}for(x=-1;x<=1;x++){for(y=-1;y<=1;y++){if(x||y) /* 8个方向*/{int i2,j2;unsigned num=0;for(i2=i+x,j2=j+y;i2>=0 && i2<=7 && j2>=0 && j2<=7;i2+=x,j2+=y){if(board->cell[i2][j2].color==(enum Color)-player){num++;}else if(board->cell[i2][j2].color==player){board->whiteNum+=(player*WHITE)*num;board->blackNum+=(player*BLACK)*num;for(i2-=x,j2-=y;num>0;num--,i2-=x,j2-=y){board->cell[i2][j2].color=player;board->cell[i2][j2].stable=0;}break;}else if(board->cell[i2][j2].color==BLANK){break;}}}}}return 0;}/** 设置棋子的稳定性(计算得分的依据),空白处除外.*/void Chessboard::setStable( Chessboard *board){int i,j;for(i=0;i<8;i++){for(j=0;j<8;j++){if(board->cell[i][j].color!=BLANK){int x,y;board->cell[i][j].stable=1;for(x=-1;x<=1;x++){for(y=-1;y<=1;y++){/* 4个方向*/if(x==0 && y==0){x=2;y=2;}else{int i2,j2,flag=2;for(i2=i+x,j2=j+y;i2>=0 && i2<=7 && j2>=0 && j2<=7;i2+=x,j2+=y){if(board->cell[i2][j2].color!=board->cell[i][j].color){flag--;break;}}for(i2=i-x,j2=j-y;i2>=0 && i2<=7 && j2>=0 && j2<=7;i2-=x,j2-=y){if(board->cell[i2][j2].color!=board->cell[i][j].color){flag--;break;}}if(flag) /* 在某一条线上稳定*/{board->cell[i][j].stable++;}}}}}}}}/** 评价棋手得分.*/int Chessboard::evaluate(Chessboard *board,enum Color player){int value=0;int i,j;setStable(board);for(i=0;i<8;i++){for(j=0;j<8;j++){value+=(board->cell[i][j].color)*(board->cell[i][j].stable);}}value+=64*board->cell[0][0].color;value+=64*board->cell[0][7].color;value+=64*board->cell[7][0].color;value+=64*board->cell[7][7].color;value-=32*board->cell[1][1].color;value-=32*board->cell[1][6].color;value-=32*board->cell[6][1].color;value-=32*board->cell[6][6].color;return value*player;}//考虑step步,选择最优方案.采用最大最小博弈和α-β剪裁算法Choice * maximin( Chessboard *board,enum Color player,int step,int min,int max, Choice *choice){int i,j,k,num;Choice *allChoices;choice->score=-MAX;choice->posX=-1;choice->posY=-1;num=board->judge(board,player);if(num==0) /* 无处落子*/{if(board->judge(board,(enum Color)-player)) /* 对方可以落子,让对方下.*/{Chessboard tempBoard;Choice nextChoice;Choice *pNextChoice=&nextChoice;board->clone(&tempBoard,board);pNextChoice=maximin(&tempBoard,(enumColor)-player,step-1,-max,-min,pNextChoice);choice->score=-pNextChoice->score;choice->posX=-1;choice->posY=-1;return choice;}else /* 对方也无处落子,游戏结束. */{int value=WHITE*(board->whiteNum) + BLACK*(board->blackNum);if(player*value>0)choice->score=MAX-1;}else if(player*value<0){choice->score=-MAX+1;}else{choice->score=0;}return choice;}}if(step<=0) /* 已经考虑到step步,直接返回得分*/{choice->score=board->evaluate(board,player);return choice;}allChoices=( Choice *)malloc(sizeof( Choice)*num);k=0;for(i=0;i<8;i++){for(j=0;j<8;j++){if(i==0 || i==7 || j==0 || j==7){if(board->cell[i][j].color==BLANK && board->cell[i][j].stable){allChoices[k].score=-MAX;allChoices[k].posX=i;allChoices[k].posY=j;k++;}}}}for(i=0;i<8;i++){for(j=0;j<8;j++){if((i==2 || i==5 || j==2 || j==5) && (i>=2 && i<=5 && j>=2 && j<=5))if(board->cell[i][j].color==BLANK && board->cell[i][j].stable){allChoices[k].score=-MAX;allChoices[k].posX=i;allChoices[k].posY=j;k++;}}}}for(i=0;i<8;i++){for(j=0;j<8;j++){if((i==1 || i==6 || j==1 || j==6) && (i>=1 && i<=6 && j>=1 && j<=6)){if(board->cell[i][j].color==BLANK && board->cell[i][j].stable){allChoices[k].score=-MAX;allChoices[k].posX=i;allChoices[k].posY=j;k++;}}}}for(k=0;k<num;k++){Chessboard tempBoard;Choice thisChoice,nextChoice;Choice *pNextChoice=&nextChoice;thisChoice=allChoices[k];board->clone(&tempBoard,board);board->putChess(&tempBoard,&thisChoice,player);pNextChoice=maximin(&tempBoard,(enumColor)-player,step-1,-max,-min,pNextChoice);thisChoice.score=-pNextChoice->score;if(thisChoice.score>min && thisChoice.score<max) /* 可以预计的更优值*/{min=thisChoice.score;choice->score=thisChoice.score;choice->posX=thisChoice.posX;choice->posY=thisChoice.posY;}else if(thisChoice.score>=max) /* 好的超乎预计*/{choice->score=thisChoice.score;choice->posX=thisChoice.posX;choice->posY=thisChoice.posY;break;}/* 不如已知最优值*/}free(allChoices);return choice;}int main(void) /////////////主函数{Chessboard board;Chessboard *pBoard=&board;enum Color player=BLANK,nowPlayer=BLACK;//声明两个enum枚举变量player,nowplayer Choice choice;Choice *pChoice=&choice;int dif=-1,step=4,success=0;char restart=' ';start: /////////////////////////////////////////////player=BLANK; /////////////////////////////////////////////nowPlayer=BLACK;dif=-1;step=4;restart=' ';int b;cout<<"输入1为人人对战,否则为人机对战:";cin>>b;if(b==1){ /////////人人对战////////////while(player!=WHITE && player!=BLACK){cout<<"\n请选择执黑棋(○)(1),或执白棋(●)(-1)\t执黑棋先下:\n";scanf("%d",&player);/////////////////////////////////////////////////////////////if(player!=WHITE && player!=BLACK){cout<<"黑白设置错误.\n";}}board.initChessboard(pBoard); /////////初始化棋盘///////////while(step<64) /* 棋盘上未下满64子*/{char *nowPlayerName="";if(nowPlayer==BLACK){nowPlayerName="黑棋(○)";}else if(nowPlayer==WHITE){nowPlayerName="白棋(●)";}if(board.judge(pBoard,nowPlayer)==0){if(board.judge(pBoard,(enum Color)-nowPlayer)==0){break; /* 双方都不能落子,游戏结束*/}cout<<nowPlayerName<<"\n无子可下.\n";}else{int i,j;board.view(pBoard);if(nowPlayer==player) /* 轮到人下*/{while(1){cout<<nowPlayerName<<"请输入棋子坐标(i,j):\n";cout<<"i=";cin>>i;i--;cout<<"j=";cin>>j;j--;pChoice->posX=i;pChoice->posY=j;if(i<0 || i>7 || j<0 || j>7 || pBoard->cell[i][j].color!=BLANK || pBoard->cell[i][j].stable==0){cout<<nowPlayerName<<"不能在"<<i+1<<","<<j+1<<"落子.";board.view(pBoard);}else{break;}}}else //另外一个人下{while(1){cout<<nowPlayerName<<"请输入棋子坐标(i,j):\n";cout<<"i=";cin>>i;i--;cout<<"j=";cin>>j;j--;pChoice->posX=i;pChoice->posY=j;if(i<0 || i>7 || j<0 || j>7 || pBoard->cell[i][j].color!=BLANK || pBoard->cell[i][j].stable==0){cout<<nowPlayerName<<"不能在"<<i+1<<","<<j+1<<"落子.";board.view(pBoard);}else{break;}}}board.putChess(pBoard,pChoice,nowPlayer);step++;cout<<nowPlayerName<<"落子于坐标"<<i+1<<","<<j+1;}nowPlayer=(enum Color)-nowPlayer; /* 换对方下*/ }board.view(pBoard);success=pBoard->whiteNum - pBoard->blackNum;if(success>0){cout<<"\n白棋(●)获胜.\n";}else if(success<0){cout<<"\n黑棋(○)获胜.\n";}else{cout<<"\n平局.\n";}cout<<"\n游戏结束!\n";while(restart!='y' && restart!='n'){cout<<"再下一盘?(y,n)\n";cin>>restart;///////////////////////////////////////////////if(restart=='y'){goto start;}}}else{ ////////////人机对战///////////// while(dif<1 || dif>60) //设置难度{cout<<"请选择难度(1~60):\n";cin>>dif;if(dif<1 || dif>60){cout<<"难度设置错误.\n";}}while(player!=WHITE && player!=BLACK){cout<<"请选择执黑棋(○)(1),或执白棋(●)(-1)"<<endl;cout<<"执黑先行:";scanf("%d",&player);if(player!=WHITE && player!=BLACK){cout<<"黑白设置错误.\n";}}board.initChessboard(pBoard); /////////////////初始化棋盘while(step<64) // 棋盘上未下满64子{char *nowPlayerName="";if(nowPlayer==BLACK){nowPlayerName="黑棋(○)";}else if(nowPlayer==WHITE){nowPlayerName="白棋(●)";}if(board.judge(pBoard,nowPlayer)==0){if(board.judge(pBoard,(enum Color)-nowPlayer)==0){break; //双方都不能落子,游戏结束}cout<<nowPlayerName<<"无子可下.\n";}else{int i,j;board.view(pBoard);if(nowPlayer==player) // 轮到人下{while(1){cout<<nowPlayerName<<",请输入棋子坐标i,j:\n";cout<<"i=";cin>>i;i--;cout<<"j=";cin>>j;j--;pChoice->posX=i;pChoice->posY=j;if(i<0 || i>7 || j<0 || j>7 || pBoard->cell[i][j].color!=BLANK || pBoard->cell[i][j].stable==0){cout<<nowPlayerName<<"不能在"<<i+1<<","<<j+1<<"落子.\n";board.view(pBoard);}else{break;}}}else //* 轮到电脑下*/{cout<<nowPlayerName<<"思考中......";pChoice=maximin(pBoard,nowPlayer,dif,-MAX,MAX,pChoice);i=pChoice->posX;j=pChoice->posY;cout<<"score="<<pChoice->score<<endl;}board.putChess(pBoard,pChoice,nowPlayer);step++;cout<<nowPlayerName<<"落子于坐标"<<i+1<<","<<j+1;}nowPlayer=(enum Color)-nowPlayer; /* 换对方下*/}board.view(pBoard);success=pBoard->whiteNum - pBoard->blackNum;if(success>0){cout<<"\n白棋(●)获胜.\n";}else if(success<0){cout<<"\n黑棋(○)获胜.\n";}else{cout<<"\n平局.\n";}cout<<"\n游戏结束!\n";while(restart!='y' && restart!='n'){cout<<"再下一盘?(y,n)\n";cin>>restart;if(restart=='y'){goto start;}}}return 0;}。

C语言编写五子棋游戏

C语言编写五子棋游戏

C语⾔编写五⼦棋游戏本⽂实例为⼤家分享了C语⾔编写五⼦棋游戏的具体代码,供⼤家参考,具体内容如下⼀、构建棋盘⾸先可以⽤⼀个⼆维数组来构建棋盘,下标表⽰位置,内容表⽰⿊⼦⽩⼦或者空位。

当数组内容为1时,该位置为⽩字,当数组为0时,该位置为⽩⼦,空位输出+int w[11][11], flag = 0;int a, b;for (int k = 0; k < 11; k++)printf("第%d列\t", k);printf("\n");for (int i = 0; i < 11; i++) {for (int j = 0; j < 11; j++) {if (w[i][j] == 0) printf("⿊\t");else if (w[i][j] == 1) printf("⽩\t");else printf("+\t");}printf("第%d⾏\n\n", i);}⼆、判断位置超范围与错误输⼊当输⼊的棋⼦坐标超出范围或者该位置已经存在棋⼦,则再次输⼊棋⼦坐标。

其中flag作为标志作为判别⿊⼿⽩⼿的标志。

if (flag == 0) {printf("⿊⾊下棋\n");scanf("%d %d", &a, &b);while (a < 0 || a>10 || b < 0 || b>10) {printf("此位置超出范围,请重新输⼊:");scanf("%d %d", &a, &b);}while (w[a][b] == 0 || w[a][b] == 1){printf("此位置已有棋⼦,请重新输⼊:");scanf("%d %d", &a, &b);}flag = 1;w[a][b] = 0;}else {printf("⽩⾊下棋\n");scanf("%d %d", &a, &b);while (a < 0 || a>10 || b < 0 || b>10) {printf("此位置超出范围,请重新输⼊:");scanf("%d %d", &a, &b);}while (w[a][b] == 0 || w[a][b] == 1){printf("此位置已有棋⼦,请重新输⼊:");scanf("%d %d", &a, &b);}三、判断胜负在五⼦棋中,出现五个棋⼦排成⼀排或者⼀列或者斜排即可判为胜出。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
yes=1;
}
}
if(i>1)/*判断上边*/
{
for(k=i-1;k>=0;k--)
if(a[k][j]==a[i][j]||!a[k][j])
break;
if(a[k][j]!=0&&k>=0)
{
for(kk=i-1;kk>k&&k>=0;kk--)
{
a[kk][j]=a[i][j];
fillellipse(120+kk*40,120+j*40,15,15);
if(key==ESC)/*跳出游戏*/
break;
else
if(key==ENTER)/*如果按键确定就可以跳出循环*/
{
if(y!=80&&a[(x-120)/40][(y-120)/40]!=1
&&a[(x-120)/40][(y-120)/40]!=2)/*如果落子位置没有棋子*/
{
if(t%2==1)/*如果是棋手1移动*/
#define ESC 0x011b /* ESC键值*/
#define ENTER 0x1c0d /* 回车键值*/
int a[8][8]={0},key,score1,score2;/*具体分数以及按键与存放棋子的变量*/
char playone[3],playtwo[3];/*两个人的得分转换成字符串输出*/
}
else/*已经有棋子就继续按键*/
continue;
}
else /*四个方向按键的判断*/
if(key==LEFT&&x>120)/*左方向键*/
{
MoveColor(x,y);
fillellipse(x,y,15,15);
SetPlayColor(t);
x-=40;
fillellipse(x,y,15,15);
if(cc>=64-score1-score2) /*如果尝试超过空格数则停步*/
{
MoveColor(x,y);
fillellipse(x,y,15,15);
break;
}
else
continue;/*如果按键无效*/
}
DoScore();/*分数的改变*/
break;/*棋盘变化了,则轮对方走棋*/
}
}
int QpChange(int x,int y,int t)/*判断棋盘的变化*/
{
int i,j,k,kk,ii,jj,yes;
yes=0;
i=(x-120)/40; /*计算数组元素的行下标*/
j=(y-120)/40; /*计算数组元素的列下标*/
SetPlayColor(t);/*设置棋子变化的颜色*/
break;
if(a[k][kk]!=0&&k<8&&kk>=0)
{
for(ii=i+1,jj=j-1;ii<k&&k<8;ii++,jj--)
{
a[ii][jj]=a[i][j];
fillellipse(120+ii*40,120+jj*40,15,15);
}
if(ii!=i+1)
yes=1;
}
}
break;
if(a[i][k]!=0&&k>=0)
{
for(kk=j-1;kk>k&&k>=0;kk--)
{
a[i][kk]=a[i][j];
fillellipse(120+i*40,120+kk*40,15,15);
}
if(kk!=j-1)
yes=1;
}
}
if(i<6)/*判断下边*/
{
for(k=i+1;k<8;k++)
}
else
if(key==RIGHT&&x<400&&y>80)/*右方向键*/
{
MoveColor(x,y);
fillellipse(x,y,15,15);
SetPlayColor(t);
x+=40;
fillellipse(x,y,15,15);
}
else
if(key==UP&&y>120)/*上方向键*/
setfillstyle(SOLID_FILL,8); /*黑色实体填充模式*/
fillellipse(500,300,15,15);
a[3][3]=a[4][4]=1;/*初始两个黑棋*/
a[3][4]=a[4][3]=2;/*初始两个白棋*/
setfillstyle(SOLID_FILL,WHITE);
fillellipse(120+3*40,120+3*40,15,15);
fillellipse(120+4*40,120+4*40,15,15);
setfillstyle(SOLID_FILL,8);
fillellipse(120+3*40,120+4*40,15,15);
fillellipse(120+4*40,120+3*40,15,15);
void DoScore(void);/*处理分数*/
void PrintScore(int n);/*输出成绩*/
void playWin(void);/*输出胜利者信息*/
/******主函数*********/
void main(void)
{
int gd=DETECT,gr;
initgraph(&gd,&gr,"c:\\tc"); /*初始化图形系统*/
switch(a[(x-120)/40][(y-120)/40])
{
case 1:
setfillstyle(SOLID_FILL,15);break; /*白色*/
case 2:
setfillstyle(SOLID_FILL,8);break; /*黑色*/
default:
setfillstyle(SOLID_FILL,BLUE); /*蓝色*/
{
a[i][kk]=a[i][j]; /*改变棋子颜色*/
fillellipse(120+i*40,120+kk*40,15,15);
}
if(kk!=j+1) /*条件成立则有棋子改变过颜色*/
yes=1;
}
}
if(j>1)/*判断左边*/
{
for(k=j-1;k>=0;k--)
if(a[i][k]==a[i][j]||!a[i][k])
DrawQp();/*画棋盘*/
playtoplay();/*人人对战*/
getch();
closegraph();/*关闭图形系统*/
}
void DrawQp()/*画棋盘*/
{
int i,j;
score1=score2=0;/*棋手一开始得分都为0*/
setbkcolor(BLUE);
for(i=100;i<=420;i+=40)
}
if(kk!=i-1)
yes=1;
}
}
if(i>1&&j<6)/*右上*/
{
for(k=i-1,kk=j+1;k>=0&&kk<8;k--,kk++)
if(a[k][kk]==a[i][j]||!a[k][kk])
break;
if(a[k][kk]&&k>=0&&kk<8)
{
foቤተ መጻሕፍቲ ባይዱ(ii=i-1,jj=j+1;ii>k&&k>=0;ii--,jj++)
void playtoplay(void);/*人人对战函数*/
void DrawQp(void);/*画棋盘函数*/
void SetPlayColor(int x);/*设置棋子第一次的颜色*/
void MoveColor(int x,int y);/*恢复原来棋盘状态*/
int QpChange(int x,int y,int z);/*判断棋盘的变化*/
/*开始往8个方向判断变化*/
if(j<6)/*往右边*/
{
for(k=j+1;k<8;k++)
if(a[i][k]==a[i][j]||a[i][k]==0)/*遇到自己的棋子或空格结束*/
break;
if(a[i][k]!=0&&k<8)
{
for(kk=j+1;kk<k&&k<8;kk++)/*判断右边*/
break;
}
t=t%2+1; /*一方走后,改变棋子颜色即轮对方走*/
cc=0; /*计数值恢复为0*/
} /*endwhile*/
}
void SetPlayColor(int t)/*设置棋子颜色*/
{
if(t%2==1)
setfillstyle(SOLID_FILL,15);/*白色*/
else
{
a[ii][jj]=a[i][j];
fillellipse(120+ii*40,120+jj*40,15,15);
相关文档
最新文档