game.c
来自「数字信号处理实验」· C语言 代码 · 共 506 行 · 第 1/2 页
C
506 行
{command=bioskey(0);
if(command==VK_ENTER) return ENTER;
else if(command==VK_DOWN)
{drawmat(jin24S,24,300,350,RED);
drawmat(ru24S,24,320,350,RED);
drawmat(tui24S,24,300,380,WHITE);
drawmat(chu24S,24,320,380,WHITE);
break;
}
}
while(1) /*当“退出”突出显示时,用户按“Enter"和向上方向键有效*/
{command=bioskey(0);
if(command==VK_ENTER) return QUITE;
else if(command==VK_UP) break;
}
}
}
void draw(int x,int y,int MorC)
/*根据MorC的值在第一、二维的坐标分别为x、y的位置下一子*/
{
int vx,vy;
int color;
chsman[x][y]=MorC;/*下子*/
if(MorC==P1) color=mancolor;
else color=computercolor;
switch(x)
{case 0:vy=170;break;
case 1:vy=240;break;
case 2:vy=310;
}
switch(y)
{case 0:vx=250;break;
case 1:vx=320;break;
case 2:vx=390;
}
setcolor(color);
circle(vx,vy,25);
}
/*根据键盘输入的z的值确定下子的第一维(x)和第二维坐标*/
int convert(int *x,int *y,char z)
{
switch(z)
{case 0x31:*x=2;*y=0;break;
case 0x32:*x=2;*y=1;break;
case 0x33:*x=2;*y=2;break;
case 0x34:*x=1;*y=0;break;
case 0x35:*x=1;*y=1;break;
case 0x36:*x=1;*y=2;break;
case 0x37:*x=0;*y=0;break;
case 0x38:*x=0;*y=1;break;
case 0x39:*x=0;*y=2;
}
return 0;
}
int man(void) /*人按1-9键下棋,小键盘上的1-9键分别对应于棋盘上的九个格*/
{
int row,col,test=1;
char k=0x30;
while(test==1||chsman[row][col]!=0)
{
while(k<0x31||k>0x39)
k=bioskey(0);
convert(&row,&col,k);
test=0;
k=0x30;
}
draw(row,col,P1);
return 0;
}
void judge(void)
{
int row, col;
int i;
/*分别用三个数组存储 棋盘上各行,各列,或者两条线上的数组元素的值的和(以下称之为权值)*/
int rskAndAtkLevlRow[3] = {0}, rskAndAtkLevlCol[3] = {0}, rskAndAtkLevlSlsh[2] = {0};
if(stepFlg == 0){
/*计算机下的第一子特别处理,优先下a[1][1]位置*/
stepFlg = 1;
if(chsman[1][1] == P1){
draw(0,0,P2);
return;
}
else{
draw(1,1,P2);
return;
}
}
stepFlg++;
/*计算各行,各列以及两斜线的权值*/
for(row = 0; row < 3; row++){
for(col = 0; col < 3; col++){
rskAndAtkLevlRow[row] += chsman[row][col];
}
}
for(col = 0; col < 3; col++){
for(row = 0; row < 3; row++){
rskAndAtkLevlCol[col] += chsman[row][col];
}
}
rskAndAtkLevlSlsh[0] = chsman[0][0] + chsman[1][1] + chsman[2][2];
rskAndAtkLevlSlsh[1] = chsman[0][2] + chsman[1][1] + chsman[2][0];
/*若权值为-2(计算机下了两了,另一位置为空),计算机攻击*/
/*攻击某一行*/
for(row = 0; row < 3; row++){
if(rskAndAtkLevlRow[row] == -2){
chkAndPutDwnRow(row)
}
}
/*攻击某一列*/
for(col = 0; col< 3; col++){
if(rskAndAtkLevlCol[col] == -2){
chkAndPutDwnCol(col)
}
}
/*攻击斜率为-1的斜线*/
if(rskAndAtkLevlSlsh[0] == -2){
for(row = 0, col = 0; row < 3; row++, col++){
if(chsman[row][col]==0)
{draw(row,col,P2);return;}
}
}
/*攻击斜率为1的斜线*/
if(rskAndAtkLevlSlsh[1] == -2){
for(row = 0, col = 2; row < 3; row++, col--)
if(chsman[row][col]==0) {draw(row,col,P2);return;}
}
/*若权值为2(人下了两子,另一位置为空),计算机防守*/
/*在某一行上防守*/
for(row = 0; row < 3; row++){
if(rskAndAtkLevlRow[row] == 2)
chkAndPutDwnRow(row)
}
/*在某一列上防守*/
for(col = 0; col< 3; col++){
if(rskAndAtkLevlCol[col] == 2)
chkAndPutDwnCol(col)
}
/*在斜率为-1的斜线上防守*/
if(rskAndAtkLevlSlsh[0] == 2){
for(row = 0, col = 0; row < 3; row++, col++)
if(chsman[row][col]==0) {draw(row,col,P2);return;}
}
/*在斜率为1的斜线上防守*/
if(rskAndAtkLevlSlsh[1] == 2){
for(row = 0, col = 2; row < 3; row++, col--)
if(chsman[row][col]==0) {draw(row,col,P2);return;}
}
/*若上述条件都不符,计算机在棋盘四角上下一子*/
for(row = 0; row < 3; row++){
for(col = 0; col < 3; col++){
if(chsman[row][col] == 0 && ((row == 0 && col == 0) || (row == 0 && col == 2) ||
(row == 2 && col == 0) || (row == 2 && col == 2)))
{draw(row,col,P2);return;}
}
}
/*若上述条件都不符,计算机在棋盘与数字键2、4、6、8的位置上下一子*/
for(row = 0; row < 3; row++){
for(col = 0; col < 3; col++){
if(chsman[row][col] == 0 && ((row == 0 && col == 1) || (row == 1 && col == 0) ||
(row == 1 && col == 2) || (row == 2 && col == 1)))
{draw(row,col,P2);return;}
}
}
}
void chessboard()
/*进入游戏后画出棋盘*/
{int i,j;
cleardevice();
setcolor(BACKGROUND);
for(j=0;j<=getmaxy();j++)
line(0,j,getmaxx(),j); /*用循环语句画背景防止屏幕闪烁*/
setcolor(RED);
line(215, 205, 425, 205);
line(215, 275, 425, 275);
line(285, 135, 285, 345);
line(355, 135, 355, 345);
drawmat(ji24S,24,145,110,computercolor); /*在棋盘边写"计算机"与"人",先下一方用黑色字,另一方白色字*/
drawmat(suan24S,24,165,110,computercolor);
drawmat(Ji24S,24,185,110,computercolor);
drawmat(ren24S,24,460,110,mancolor);
}
/*判断游戏是否结束,若结束则输出结果并返回1,否则返回零*/
int chkresult(void)
{int i;
for(i = 0; i < 3; i++)
if(chsman[i][0] + chsman[i][1] + chsman[i][2] == -3 || /*计算机赢*/
chsman[0][i] + chsman[1][i] + chsman[2][i] == -3 ||
chsman[0][0] + chsman[1][1] + chsman[2][2] == -3 ||
chsman[0][2] + chsman[1][1] + chsman[2][0] == -3)
{drawmat(ying24S,24,165,150,RED);
drawmat(shu24S,24,460,150,WHITE);
return 1;
}
for(i = 0; i < 3; i++)
if(chsman[i][0] + chsman[i][1] + chsman[i][2] == 3 || /*人赢*/
chsman[0][i] + chsman[1][i] + chsman[2][i] == 3 ||
chsman[0][0] + chsman[1][1] + chsman[2][2] == 3 ||
chsman[0][2] + chsman[1][1] + chsman[2][0] == 3)
{drawmat(ying24S,24,460,150,RED);
drawmat(shu24S,24,165,150,WHITE);
return 1;
}
if(stepFlg==5)/*计算机已下五子(计算机先下)或四子(人先下), 和棋*/
{drawmat(he24S,24,293,110,RED);
drawmat(qi24S,24,324,110,RED);
return 1;
}
return 0;
}
void compete() /*进入游戏,并对本函数对下棋的一些参数初始化*/
{int i,j;
int result;
stepFlg = 0;
for(i=0;i<3;i++) /*初始化棋盘状态*/
for(j=0;j<3;j++)
chsman[i][j]=0;
randomize();
firstone=random(2); /*随机让人或计算机先下第一子*/
if(firstone==MAN) {mancolor=BLACK;computercolor=WHITE;} /*先下者用黑子*/
else {mancolor=WHITE;computercolor=BLACK;}
chessboard(); /*画棋盘*/
while(1)
{
if(firstone==MAN) /*先后下子直至结束*/
{man();
if(chkresult()==1) {getch();return;}
judge();
if(chkresult()==1) {getch();return;}
}
else
{judge();
if(chkresult()==1) {getch();return;}
man();
if(chkresult()==1) {getch();return;}
}
}
}
int main(void)
{ int k=ENTER;
initgr(); /* BGI初始化 */
while(k==ENTER)
{k=pictureone();
if(k==QUITE) break;
else compete();
}
closegraph();
return 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?