用c语言写五子棋

这是大一上学期要求写的课设,没用到指针,坐标的控制的代码还是从网上搜的,也借鉴了很多其他人的代码,应该挺容易理解的,因为没用到指针,最难的就只有判断连成五子的那个算法了,可能刚开始做的时候会觉得很难,尽量先自己想一想怎么去判断,实在想不出再看看别人的算法,因为这样更容易理解。

代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<conio.h>

#define N 100

char c, j;
int score1=0, score2=0;
int map[N][N]={0};          //定义棋盘的初始值为0

void gamestart();
void help();
void gotoxy(int ,int );
void creatmap();            //画棋盘
void playchess();           //玩五子棋
int judge1(int ,int );      //判断玩家一是否连成五子
int judge2(int ,int );      //判断玩家二是否连成五子
void renew();               //将棋盘恢复成初始值0
void scoring(int );         //计分
void game_over();           //一局游戏结束的画面

int main()
{
    system("COLOR F0");     //设置背景色和棋盘色
    gamestart();
    playchess();
    return 0;
}

/*----------------------------------------------------------*/

void gamestart()            //游戏开始的界面
{
    gotoxy(45,15);
    printf("欢迎来到五子棋游戏");
    gotoxy(45,18);
    printf("请按任意键进入帮助界面");
    getch();
    system("cls");
    help();
}

/*-----------------------------------------------------------*/

void help()
{
    gotoxy(45,10);
    printf("请在英文状态下进行五子棋对弈");
    gotoxy(45,13);
    printf("一号玩家为w、s、a、d控制上下左右,空格键落子");
    gotoxy(45,14);
    printf("二号玩家为↑、↓、←、→控制上下左右,回车键落子");
    gotoxy(45,15);
    printf("按Backspace键可悔棋,按ESC键退出游戏");
    gotoxy(45,18);
    printf("请按任意键确定进入游戏界面");
    getch();
    system("cls");
}

/*-----------------------------------------------------------*/

void game_over()
{
	char z;
	system("cls");
	gotoxy(45,10);
	printf("游戏结束,是否开始新一局游戏?");
	gotoxy(45,11);
	printf("继续游戏请按Y/y,结束游戏请按N/n");
	lable3:                       //设置一个标签三
		{
			z=getch();
			if(z!='Y' && z!='y' && z!='N' && z!='n')
			{
				gotoxy(45,14);
				printf("输入错误,请重新输入");
				goto lable3;      //重新进行标签三里的语句
			}
			if(z=='Y' || z=='y')
			{
				system("cls");
				renew();
				playchess();
			}
			if(z=='Z' || z=='n')
			{
				exit(0);
			}
		}
}

/*-----------------------------------------------------------*/

void gotoxy(int x, int y) //定位到第y行的第x列
{
    int xx=0x0b;
    HANDLE hOutput;
    COORD loc;
    loc.X = x;
    loc.Y=y;
    hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hOutput, loc);
    return;
}

/*------------------------------------------------------------*/

void gotoprint(int x,int y)
{
    gotoxy(x,y);
    printf("┬");
}
void gotoprint2(int x,int y)
{
    gotoxy(x,y);
    printf("├ ");
}
void gotoprint3(int x,int y)
{
    gotoxy(x,y);
    printf("┼");
}
void gotoprint4(int x,int y)
{
    gotoxy(x,y);
    printf("┤");
}
void gotoprint5(int x,int y)
{
    gotoxy(x,y);
    printf("┴");
}
void gotoprint6(int x,int y)
{
    gotoxy(x,y);
    printf("-");
}
void gotoprint7(int x,int y)
{
    gotoxy(x,y);
    printf("★");
}

/*-------------------------------------------------------------*/

void creatmap()
{
    int i, j;
    gotoxy(0,1);
    printf("┌");
    for(i=1;i<=39;i++)                 //横轴上的必须翻倍才与纵轴相等!!!!
    {
        if(i%2!=0)
        {
            gotoprint6(i,1);
            gotoprint6(i,21);
        }
        else
        {
            gotoprint(i,1);
            gotoprint5(i,21);
        }
    }
    gotoxy(0,21);
    printf("└");
    gotoxy(40,1);
    printf("┐");
    for(i=2;i<=20;i++)
    {
        gotoprint2(0,i);
        gotoprint4(40,i);
    }
    for(i=2;i<40;i+=2)
    {
        for(j=2;j<=20;j++)
        gotoprint3(i,j);
    }
    gotoxy(40,21);
    printf("┘");
    printf("\n");
}

/*-------------------------------------------------------------*/

void playchess()
{
    creatmap();
    gotoxy(45,5);
    printf("请在棋盘内落子,边缘不可落子");
    int whoturn=0;    //判断一号玩家还是二号玩家落子
    int a=2, b=2;     //游戏刚开始时光标所在的位置
    int q, w, e, r;   //悔棋时用
    while(1)
    {
        if(whoturn%2==0)
        {
            lable1:                          //设置标签一,用于一号玩家悔棋
            {
                c=1;
                gotoxy(18,0);
                printf("黑子");
                gotoxy(45,10);
                printf("现在轮到一号玩家,请落子");   //提示一号玩家落子
                while(c!=' ')
                {
                    c=getch();
                    switch (c)
                    {
                    case 'w':                //向上,纵坐标减一
                        {
                            gotoxy(a,b-1);
                            b-=1;
                            break;
                        }
                    case 's':                //向下,纵坐标加一
                        {
                            gotoxy(a,b+1);
                            b+=1;
                            break;
                        }
                    case 'a':                //向左,横坐标减二
                        {
                            gotoxy(a-2,b);
                            a-=2;
                            break;
                        }
                    case 'd':                //向右,横坐标加二
                        {
                            gotoxy(a+2,b);
                            a+=2;
                            break;
                        }
                    }
                    q=a,w=b;
                    if(c==' ')               //按空格键落子
                    {
                        gotoxy(a,b);
                        if(map[a][b]==1 || map[a][b]==2)     //如果所要下的地方为已经下过的则重新选地方下子
                            goto lable1;
                        map[a][b]=2;         //将一号玩家落子的地方的值变为2,以判断一号玩家是否连成五子
                        printf("●");         //一号玩家为黑子
                        if(judge1(a,b)==1)   //一号玩家连成五子
                        {
                            scoring(1);
                            gotoxy(45,15);
                            printf("恭喜一号玩家胜利!!!\a");
                            Sleep(2000);     //延迟两秒再清屏开始新一局游戏
                            game_over();     //进入游戏结束画面
                        }
                    }
                    if(c==8)                 //Backspace键的ASCII码为8
                    {
                        gotoprint3(e,r);
                        whoturn--;           //二号玩家悔棋,回到上一次的二号玩家
                        goto lable2;
                    }
                    if(c==27)                //ESC键的ASCII码为27
                    {
                        system("cls");
                        exit(0);             //实现按ESC键退出游戏的功能
                    }
                }
            }
        }
        if(whoturn%2==1)
        {
            lable2:                          //设置标签二,用于二号玩家悔棋
                {
                    j=1;
                    gotoxy(18,0);
                	printf("白子");
                    gotoxy(45,10);
                    printf("现在轮到二号玩家,请落子");  //提示二号玩家落子
                    while(j!=13)
                    {
                        j=getch();
                        if(j==0xE0)          //方向键按一次会有两个值,所以得接收两次
                            j=getch();
                        switch (j)
                        {
                        case 72:             //向上,纵坐标减一
                            {
                                gotoxy(a,b-1);
                                b-=1;
                                break;
                            }
                        case 80:             //向下,纵坐标加一
                            {
                                gotoxy(a,b+1);
                                b+=1;
                                break;
                            }
                        case 75:             //向左,横坐标减二
                            {
                                gotoxy(a-2,b);
                                a-=2;
                                break;
                            }
                        case 77:             //向右,横坐标加二
                            {
                                gotoxy(a+2,b);
                                a+=2;
                                break;
                            }
                        }
                        e=a,r=b;
                        if(j==13)            //Enter键的ASCII码为13,按Enter键时落子
                        {
                            gotoxy(a,b);
                            if(map[a][b]==2 || map[a][b]==1)     //如果所要下的地方为已经下过的则重新选地方下子
                                goto lable2;
                            map[a][b]=1;     //将二号玩家落子的地方的值变为1,以判断二号玩家是否连成五子
                            printf("○");    //二号玩家为白子
                            if(judge2(a,b)==1)//二号玩家连成五子
                            {
                                scoring(2);
                                gotoxy(45,15);
                                printf("恭喜二号玩家胜利!!!\a");
                                Sleep(2000); //延迟两秒后清屏
                                game_over(); //进入游戏结束画面
                            }
                        }
                        if(j==8)             //一号玩家悔棋
                        {
                            gotoprint3(q,w);
                            whoturn--;       //回到上一次的一号玩家
                            goto lable1;
                        }
                        if(j==27)            //退出
                        {
                            system("cls");
                            exit(0);
                        }
                    }
                }
        }
        whoturn++;
        if(whoturn==360)                    //整个棋盘下满还未分出胜负为平局
        {
            gotoxy(45,15);
            printf("平局");
            Sleep(2000);                    //延迟两秒后清屏
            system("cls");
            renew();                        //清除上一句的痕迹
            playchess();                    //开始新的一局
        }
    }
}

/*----------------------------------------------------------*/

int judge1(int x,int y)  //判断一号玩家是否胜利
{
    int i, j;
	for(i=x-8;i<=x+8;i++)//判断横
	{
	    if(map[i][y]==2 && map[i+2][y]==2 && map[i+4][y]==2 && map[i+6][y]==2 && map[i+8][y]==2)
        {
            gotoprint7(i,y),gotoprint7(i+2,y),gotoprint7(i+4,y),gotoprint7(i+6,y),gotoprint7(i+8,y);   //若胜利便将连成了五个子变为五角星
            return 1;
        }
        else
            continue;
	}
	for(j=y-4;j<=y+4;j++)//判断竖
	{
	    if(map[x][j]==2 && map[x][j+1]==2 && map[x][j+2]==2 && map[x][j+3]==2 && map[x][j+4]==2)
        {
            gotoprint7(x,j),gotoprint7(x,j+1),gotoprint7(x,j+2),gotoprint7(x,j+3),gotoprint7(x,j+4);
            return 1;
        }
        else
            continue;
	}
	for(i=x-8,j=y-4;i<=x+8;i+=2,j++)//判断右斜
	{
	    if(map[i][j]==2 && map[i+2][j+1]==2 && map[i+4][j+2]==2 && map[i+6][j+3]==2 && map[i+8][j+4]==2)
        {
            gotoprint7(i,j),gotoprint7(i+2,j+1),gotoprint7(i+4,j+2),gotoprint7(i+6,j+3),gotoprint7(i+8,j+4);
            return 1;
        }
        else
            continue;
	}
	for(i=x-8,j=y+4;i<=x+8;i+=2,j--)//判断左斜
	{
	    if(map[i][j]==2 && map[i+2][j-1]==2 && map[i+4][j-2]==2 && map[i+6][j-3]==2 && map[i+8][j-4]==2)
        {
            gotoprint7(i,j),gotoprint7(i+2,j-1),gotoprint7(i+4,j-2),gotoprint7(i+6,j-3),gotoprint7(i+8,j-4);
            return 1;
        }
        else
            continue;
	}
    return 0;
}

/*----------------------------------------------------------*/

int judge2(int x,int y)  //判断二号玩家是否胜利
{
	int i, j;
	for(i=x-8;i<=x+8;i++)//判断横
	{
	    if(map[i][y]==1 && map[i+2][y]==1 && map[i+4][y]==1 && map[i+6][y]==1 && map[i+8][y]==1)
        {
            gotoprint7(i,y),gotoprint7(i+2,y),gotoprint7(i+4,y),gotoprint7(i+6,y),gotoprint7(i+8,y);
            return 1;
        }
        else
            continue;
	}
	for(j=y-4;j<=y+4;j++)//判断竖
	{
	    if(map[x][j]==1 && map[x][j+1]==1 && map[x][j+2]==1 && map[x][j+3]==1 && map[x][j+4]==1)
        {
            gotoprint7(x,j),gotoprint7(x,j+1),gotoprint7(x,j+2),gotoprint7(x,j+3),gotoprint7(x,j+4);
            return 1;
        }
        else
            continue;
	}
	for(i=x-8,j=y-4;i<=x+8;i+=2,j++)//判断右斜
	{
	    if(map[i][j]==1 && map[i+2][j+1]==1 && map[i+4][j+2]==1 && map[i+6][j+3]==1 && map[i+8][j+4]==1)
        {
            gotoprint7(i,j),gotoprint7(i+2,j+1),gotoprint7(i+4,j+2),gotoprint7(i+6,j+3),gotoprint7(i+8,j+4);
            return 1;
        }
        else
            continue;
	}
	for(i=x-8,j=y+4;i<=x+8;i+=2,j--)//判断左斜
	{
	    if(map[i][j]==1 && map[i+2][j-1]==1 && map[i+4][j-2]==1 && map[i+6][j-3]==1 && map[i+8][j-4]==1)
        {
            gotoprint7(i,j),gotoprint7(i+2,j-1),gotoprint7(i+4,j-2),gotoprint7(i+6,j-3),gotoprint7(i+8,j-4);
            return 1;
        }
        else
            continue;
	}
    return 0;
}

/*----------------------------------------------------------*/

void renew()
{
    int i, j;
    for(i=0;i<=50;i++)
        for(j=0;j<=50;j++)
    {
        map[i][j]=0;
    }
}

/*----------------------------------------------------------*/

void scoring(int x)
{
	FILE* fp;
	char read[100];
	if((fp=fopen("score.txt","w+"))==NULL)
	{
	    gotoxy(55,10);
	    printf("The file can not be opened\n");
		exit(1);
	}
	if(x==1)
		score1+=1;
	if(x==2)
		score2+=1;
	fputs("player1:   ",fp);
	fprintf(fp,"%d   ",score1);
	fputs("player2:   ",fp);
	fprintf(fp,"%d",score2);
	rewind(fp);                           //将指针回到文件开头
    fgets(read,30,fp);                    //读取文件里的内容,即记分板
	gotoxy(45,18);
	printf("%s",read);                    //输出文件内容
}

 

发现个不能悔棋的bug,当初上传的时候测试是可以的,一年半后的今天突然发现不能悔棋了,qqgg,等我有空了再修改一下。

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值