小萝莉五子棋(高能绕行)

问题及代码:

/*
*copyright (t) 2016,烟台大学计算机学院
*All rights reserved.
*文件名称:test.cpp
*作者:张晴晴
*完成日期:2016年6月30日
*版本号:v1.0
*问题描述:五子棋
*输入描述:按照方式操作进行五子棋游戏,落子还可以悔棋
*程序输出:五子棋对战的实况,判断输赢
*/

                     //五子棋小游戏

#include <stdio.h>
#include<windows.h>
#include <stdlib.h>
#include<conio.h>			//使用getch()函数

int startchoice,winner,player,Q[200][200]= {0};		//Q数组记录旗子
char button;										//读入键盘输入的指令,如→

struct Point			//点坐标的结构体
{
    int x,y;
} point,game_xy;

struct Piece			//棋子的坐标记录
{
    struct Point coord;
    struct Piece *fore;
};

struct Piece *head,*p,*ptr,*ptr1;

void goto_xy(int x, int y)          //光标移动函数
{
    COORD c;
    c.X=2*x;
    c.Y=y;
    SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c);
}

void Init()				//初始化函数,将记录棋子的数组初始化
{
    for(int i=0; i<200; i++)
        for(int j=0; j<200; j++)
            Q[i][j]=0;

    startchoice=0;
	player=1;
    p=(struct Piece *)malloc(sizeof(struct Piece));
    head=p;
}

void Welcome()      //欢迎界面
{
	system("color 2F");				//#include<windows.h>  2 背景绿色  F  字体亮白色
    goto_xy(10,3);
    printf("—→");
    goto_xy(17,1);
    printf("主菜单");
    goto_xy(13,3);
    printf("   ***人人对战***");
    goto_xy(13,4);
    printf("     ***退出***");
    point.x=12;
    point.y=3;
    goto_xy(0,0);
}

void ShowWho()							//显示轮到哪一方下棋
{
    goto_xy(17,22);
    if(player==0)
        printf("轮到甲方落子");
    else
        printf("轮到乙方落子");
    goto_xy(point.x,point.y);
}

void Draw()                //绘画游戏界面
{
	game_xy.x=10;
    game_xy.y=3;
    system("cls");
    system("color 3F");			//3 湖蓝色  F 亮白色
    goto_xy(15,1);
    printf("欢迎play our 五子棋!");
    /*goto_xy(29,22);
    printf("重新开始         r");*/
    goto_xy(1,22);
    printf("悔棋             b");
    goto_xy(1,23);
    printf("退出           ESC");

	const int i=8;				//const 定义的数据不可以被改变 而且修改数据比较方便
    const int j=19;
	const int k=3;
    goto_xy(game_xy.x-i,game_xy.y+k);			//输出甲方的下棋方法
    printf("甲方:    ●");
    goto_xy(game_xy.x-i,game_xy.y+k+2);
    printf("移动:  上   ↑");
    goto_xy(game_xy.x-i,game_xy.y+k+4);
    printf("        下   ↓");
    goto_xy(game_xy.x-i,game_xy.y+k+6);
    printf("        左   ←");
    goto_xy(game_xy.x-i,game_xy.y+k+8);
    printf("        右   →");
	goto_xy(game_xy.x-i,game_xy.y+k+10);
	printf("落子:   Enter");

	goto_xy(game_xy.x+j,game_xy.y+k);				//输出乙方的下棋方法
    printf("乙方:    ○");
    goto_xy(game_xy.x+j,game_xy.y+k+2);
    printf("移动:  上   ↑");
    goto_xy(game_xy.x+j,game_xy.y+k+4);
    printf("        下   ↓");
    goto_xy(game_xy.x+j,game_xy.y+k+6);
    printf("        左   ←");
    goto_xy(game_xy.x+j,game_xy.y+k+8);
    printf("        右   →");
	goto_xy(game_xy.x+j,game_xy.y+k+10);
	printf("落子:   Enter");

    for(int k1=0; k1<200; k1++)					//初始化棋子记录,在第二局时有明确的作用
        for(int k2=0; k2<200; k2++)
            Q[k1][k2]=0;

    for(int i=0; i<18; i++)					//画棋盘
    {

        if(i==0)							//画第一行
        {
            goto_xy(10,i+3);
            printf("┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐");

        }
        if(i!=0&&i!=17)						//画出中间16行
        {
            goto_xy(10,i+3);
            printf("├┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┤");
        }
        if(i==17)							//画最后一行
        {
            goto_xy(10,i+3);
            printf("└┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┘");
        }
    }
    point.x=19;
    point.y=12;
    goto_xy(19,12);
}

void Clean()					//清除—→运动的轨迹
{
    goto_xy(10,3);
    printf("     ");
    goto_xy(24,3);
    printf("     ");
    goto_xy(10,4);
    printf("     ");
    goto_xy(24,4);
    printf("     ");
}

void menu_choose(char press)			//选择游戏还是退出
{
	if(press==72)				//↑的ASCLL码
    {
        if(point.y==3)
            point.y=4;
        else
            point.y=3;
        Clean();
        goto_xy(10,point.y);
        printf("—→");
    }
    if(press==80)			//↓的ASCLL码
    {
        if(point.y==4)
			point.y=3;
        else
			point.y=4;
        Clean();
        goto_xy(10,point.y);
        printf("—→");
    }
    if(press==13)		// 13:回车键的ASCLL码
    {
        startchoice=point.y-2;				//startchoice 为1或2
    }
}

void go_back(int x1,int y1)					//悔棋函数
{
    goto_xy(x1,y1);
    if(x1==10)
    {
        if(y1==3)
        {
            printf("┌");
        }
        else if(y1==20)
        {
            printf("└");
        }
        else
        {
            printf("├");
        }
    }
    else if(x1==27)
    {
        if(y1==3)
        {
            printf("┐");
        }
        else if(y1==20)
        {
            printf("┘");
        }
        else
        {
            printf("┤");
        }
    }
    else
    {
        if(y1==3)
        {
            printf("┬");
        }
        else if(y1==20)
        {
            printf("┴");
        }
        else
        {
            printf("┼");
        }
    }
    Q[point.x][point.y]=0;			//在数组中将弹出的棋子对应的数据设为0
    goto_xy(x1,y1);
}

void Record()              //记录棋子的情况
{

    p->coord.x=point.x;
    p->coord.y=point.y;
    ptr=p;
    p=(struct Piece *)malloc(sizeof(struct Piece));
    p->fore=ptr;

    ShowWho();
    Q[point.x][point.y]=player+1;
    if(player)
    {
        player=0;
        return;
    }
    player=1;
    goto_xy(point.x,point.y);
}

void PutDown()					//显示落子函数
{
    if(Q[point.x][point.y]==0)				//先判断该位置是否有棋子
    {
        if(player)
        {
            printf("●");
            printf("\a");					//'\a'表示蜂鸣声
            Record();
        }
		else
        {
            printf("○");
            printf("\a");
            Record();
        }
        goto_xy(point.x,point.y);
    }
}

void Play(char ch)					//键盘的操作 移动光标 下棋和悔棋操作
{
    if(ch==72)			//↑的ASCLL码 光标上移
    {
        if(point.y<=3)
			point.y=20;
        else
			point.y--;
        goto_xy(point.x,point.y);

    }
    if(ch==75)						//←的ASCLL码    光标左移
    {
        if(point.x<=10)
			point.x=27;
        else
			point.x--;
        goto_xy(point.x,point.y);

    }
    if(ch==77)						//→的ASCLL码  光标右移
    {
        if(point.x>=27)
			point.x=10;
        else
			point.x++;
        goto_xy(point.x,point.y);

    }
    if(ch==80)						//↓的ASCLL码   光标下移
    {
        if(point.y>=20)
			point.y=3;
        else
			point.y++;
        goto_xy(point.x,point.y);

    }
    if(ch==13)				//回车键的ASCLL码		下棋
    {
        PutDown();
    }

    if(button=='b'||button=='B')       //悔棋的操作
    {
        ptr1=p;
        if(p!=head)
        {
            p=p->fore;
            free(ptr1);
            point.x=p->coord.x;
            point.y=p->coord.y;
            go_back(point.x,point.y);
        }
    }
}

int Judge()
{
    int count=0;
    int pp=player==0?2:1;				//三目运算
    for(int c=0; c<200; c++)
    {
        for(int r=0; r<200; r++)
        {
            if(Q[r][c]!=pp)
                continue;
			//检查列
            int rr=r;
            int cc=c;
            while(--cc>=3 &&Q[rr][cc]==pp)
				count++;
            cc=c;
            while(++cc<23 &&Q[rr][cc]==pp)
				count++;
            cc=c;
            if(count>=4)
                return pp;
			//检查行
            count=0;
            while(--rr>=10 &&Q[rr][cc]==pp)
				count++;
            rr=r;
            while(++rr<30 &&Q[rr][cc]==pp)
				count++;
            rr=r;
            if(count>=4)
                return pp;
			//检查反斜边
            count=0;
            cc--;
            rr--;
            while((cc>=3||rr>=10) &&Q[rr][cc]==pp)
            {
                count++;
                cc--;
                rr--;
            }
            rr=r;
            cc=c;
            cc++;
            rr++;
            while((cc<23||rr<30) &&Q[rr][cc]==pp)
            {
                count++;
                cc++;
                rr++;
            }
            rr=r;
            cc=c;
            if(count+1>=5)
                return pp;
			//检查正斜边
            count=0;
            cc++;
            rr--;
            while((cc<23||rr>=10) &&Q[rr][cc]==pp)
            {
                count++;
                cc++;
                rr--;
            }
            rr=r;
            cc=c;
            cc--;
            rr++;
            while((cc>=3||rr<30) &&Q[rr][cc]==pp)
            {
                count++;
                cc--;
                rr++;
            }
            rr=r;
            cc=c;
            if(count+1>=5)
                return pp;
            count=0;
        }
    }
    return 0;
}

int main(void)
{
	system("color 4E");
	printf("\n			       欢迎play五子棋!");
	goto_xy(15,3);
	printf("作者:小萝莉");
	goto_xy(17,5);
	printf(" HE·Honda");
	goto_xy(17,7);
	printf(" ZSSB");
	Sleep(3000);
	system("cls");
    while(1)
    {
        Init();						//初始化
        int winner=0;
        Welcome();					//欢迎界面

        while(1)					//读取菜单选项
        {
            char choice=getch();
            menu_choose(choice);
            if(startchoice!=0)
                break;
        }

        if(startchoice==1)				//选择人人对战
        {

            Draw();
            goto_xy(17,22);
            printf("轮到甲方落子");
            goto_xy(point.x,point.y);

            while(1)
            {
                button=getch();
                Play(button);      //读取键盘的操作 移动光标 下棋和悔棋操作

                if(button==27)			//ESC的ASCLL码
                {
					if(MessageBox(NULL,TEXT("确定退出?"),TEXT(""),MB_ICONQUESTION|MB_OKCANCEL)==IDOK)
					{
						system("cls");
						printf("\n				谢谢使用!\n");
						return 0;
					}
				}

                if(button==13)				//回车键ASCLL码		按下后开始判断输赢
                    winner=Judge();

                if(winner!=0)
                {
                    goto_xy(15,24);
                    if(winner==2)
                    {
                        printf("恭喜!甲方赢!\n");
                    }
                    if(winner==1)
                    {
                        printf("恭喜!乙方赢!\n");
                    }
                }

                if(winner!=1&&winner!=2)
                {
                    continue;
                }

                goto_xy(13,22);
                printf("   继续游戏?(Y/N):    ");
                while(1)
                {
                    button=getch();
                    if(button=='n'||button=='N'||button=='y'||button=='Y')
                        break;
                }

                if(button=='n'||button=='N')
				{
					if(MessageBox(NULL,TEXT("  确定退出?"),TEXT(""),MB_ICONQUESTION|MB_OKCANCEL)==IDOK)
					{
						system("cls");
						printf("\n				谢谢使用!\n");
						return 0;
					}
				}

                if(button=='y'||button=='Y')
                {
                    winner=0;
                    system("cls");
                    break;
                }

            }
        }

        if(startchoice==2)
        {
			if(MessageBox(NULL,TEXT("  确定退出?"),TEXT(""),MB_ICONQUESTION|MB_OKCANCEL)==IDOK)
			{
				printf("\n\n				谢谢使用!\n");
				return 0;
			}
		}
    }
    return 0;
}




运行结果:

学习心得:

感觉好高能所以就保存发博文了,很多界面啥的搞不懂

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

早日退休过上不劳而获生活

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值