这个是同学的作品 不是我写的
#include
#include
#include
//头文件
// 定义play1和play2的操作
#define play1up 'w'
#define play1down 's'
#define play1left 'a'
#define play1right 'd'
#define play2up '8'
#define play2down '5'
#define play2left '4'
#define play2right '6'
#define play1lq ' '
#define play2lq '0'
#define N 20
#define playnext 'q'
#define exit 'e'
int m=1;
int p[N][N];/*记录棋盘落子情况*/
char q[N][N];/*记录棋盘交叉点棋子种类*/
struct zuobiao
{
int x;
int y;
}weizhi;
/*注意以上为全局声明部分,应用到下面所有调用函数与主函数*/
void gotoxy(int x, int y) /*(屏幕)建立光标移动位置的坐标函数*/
{
COORD c; // COORD表示一个结构体的字符在控制台屏幕上的坐标
c.X=x;
c.Y=y;
SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c); // 定位光标位置的函数 将光标移动到指定位置 一个特定的标准设备取得句柄
}
void drawqipan()/*建立棋盘*/
{
int i,j;
for(i=0;i
{
for(j=0;j
{
p[i][j]=0; // 只是单纯的赋初值 无直接关系
q[i][j]=0; // 只是单纯的赋初值 无直接关系
printf("十");
}
printf("\n");
}
}
void movegb(char press)/*(非屏幕)光标的移动*/
{
switch(press)
{
case play1up:if(weizhi.y>-1)weizhi.y--;if(weizhi.y<0)weizhi.y=19;break;
/*对手1光标向上移动*/
case play1down:if(weizhi.y<20)weizhi.y++;if(weizhi.y>19)weizhi.y=0;break;
/*对手1光标向下移动*/
case play1left:if(weizhi.x>-1)weizhi.x--;if(weizhi.x<0)weizhi.x=19;break;
/*对手1光标向左移动*/
case play1right:if(weizhi.x<20)weizhi.x++;if(weizhi.x>19)weizhi.x=0;break;
/*对手1光标向右移动*/
case play2up:if(weizhi.y>-1)weizhi.y--;if(weizhi.y<0)weizhi.y=19;break;
/*对手2光标向上移动*/
case play2down:if(weizhi.y<20)weizhi.y++;if(weizhi.y>19)weizhi.y=0;break;
/*对手2光标向下移动*/
case play2left:if(weizhi.x>-1)weizhi.x--;if(weizhi.x<0)weizhi.x=19;break;
/*对手2光标向左移动*/
case play2right:if(weizhi.x<20)weizhi.x++;if(weizhi.x>19)weizhi.x=0;break
;/*对手2光标向右移动*/
}
gotoxy(2*weizhi.x,weizhi.y); //(调用函数gotoxy)将屏幕的光标移动到指定位置
}
void luozi(char press)
{
static t=0;/*代表坐标交叉点有无棋子的状态*/
if(press==play1lq)
if(t==0&&p[weizhi.x][weizhi.y]==0)
{
printf("●");
gotoxy(2*weizhi.x,weizhi.y);
q[weizhi.x][weizhi.y]=press; // 判断此处坐标的棋子种类为player1的操作
p[weizhi.x][weizhi.y]=1; // 判断此处坐标有无落子(有落子为1无落子为0)
t=1; // 交换player1的操作
}
if(press==play2lq)
if(t==1&&p[weizhi.x][weizhi.y]==0)
{
printf(" ");
gotoxy(2*weizhi.x,weizhi.y);
q[weizhi.x][weizhi.y]=press; // 判断此处坐标的棋子种类为player2的操作
p[weizhi.x][weizhi.y]=1; // 判断此处坐标有无落子(有落子为1无落子为0)
t=0; // 交换player2操作
}
}
void judgewin(char press)//判断输赢
{
int i,count1,count2=0,count3=0;
struct zuobiao p;
for(i=0;i<4;i++) // 外循环4次(有多少种判定输赢的次数就有多少次外循环)
{
for(count1=4;count1>=-4;count1--) // 满足条件要内循环9次(例如case 0中若五子连在一直线上:若第一个五子的落子为weizhi.x=0,直到第4个五子的落子/第四个循环:p.x=0=count1=weizhi.x,第五次循环weizhi.x-count1开始大于0,第五次开始count2+=1方可判断输赢)
{
switch(i)
{
case 0:p.x=weizhi.x-count1;p.y=weizhi.y;break;
/*从左往右判断是否有五子连续在一直线上*/
case 1:p.x=weizhi.x;p.y=weizhi.y+count1;break;
/* 从上往下判断是否有五子连续在一直线上*/
case 2:p.x=weizhi.x-count1;p.y=weizhi.y+count1;break;
/* 从左上往右下判断是否有五子连续在一直线上*/
case 3:p.x=weizhi.x-count1;p.y=weizhi.y-count1;break;
/* 从左下往右上判断是否有五子连续在一直线上*/
}
if(p.x>=0&&p.y>=0)
{
if(q[p.x][p.y]==play1lq) // 判断棋子种类是否为play1的操作
{
count2++;count3=0;} // 若为play1操作才使count2++
if(q[p.x][p.y]==play2lq) // 判断棋子种类是否为play2的操作
{
count3++;count2=0;} // 若为play2操作才使count3++
}
}
// 分开与上面循环体无关
if(count2>=5)
{
gotoxy(20,20);printf("the side of ● wins\n");printf("If you want to play again...\nPlease do Q! Or else do E!");break;}
else
count2=0;
if(count3>=5)
{
gotoxy(20,20);printf("the side of ○ wins\n");printf("If you want to play again...\nPlease do Q! Or else do E!");break;}
else
count3=0;
}
}
void main() /*主函数*/
{
char press;
system("COLOR 2f"); /*COLOR为变化控制台颜色 2为背景颜色 f为前景颜色*/
PlaySoundA("H:\\Deep Side - Booty Music (扭臀之歌).wav",NULL,SND_FILENAME|SND_ASYNC);
drawqipan();
gotoxy(0,0);
// 开始进入循环结构 注意:每次落子一个就jugewin判断棋子是否为五子
while(m) // 进入死循环 直到m=0为假则退出循环
{
press=getch(); // 不回显函数,当用户按下某个字符时,函数自动读取,无需按回车 头文件
movegb(press); // 光标的移动
switch(press)
{
case play1lq: // 与case play2lq同样的语句 所以可省略
case play2lq:luozi(press);judgewin(press);break; // 循环(每次落子一个然后判断一个) 所以jugewin函数中最多要内循环9次才可以
case playnext:system("cls");drawqipan();gotoxy(0,0);break; // “cls”清除控制台的数据 重新玩则继续循环体所以要附加两个语句(drawqipan与gotoxy)
case exit : m=0;break; // 使m=0,则循环结束退出游戏
default :break;
}
}
}