五子棋游戏

· · 个人记录

游戏内容:大家都会玩的五子棋游戏。一方为黑,一方为白,黑先下。自已的五颗棋子连成一条线,并且连成的棋子中间不能有对方的棋子,就可以获胜。连成的一条线可以是横着的,可以是竖着的,也可以是斜着的。
操作说明:游戏开始后,鼠标放到下棋的位置按下空格即可下棋。如果任意一方胜利或平局将会显示结果页面2秒然后再来一局。
预估更新:计分系统。
作者留言:第1个自己制作的游戏,如果有什么建议或漏洞,希望大家能在评论里留言。
注意事项:为防止按下按键后执行多次对应语句,每按完一次键会有500ms冷却。

更新日志:
2022.03.01:制作游戏框架,下棋判断,胜负判断。将棋盘改为15*15,加入黑白棋与总数计数。
2022.03.02:增加‘R'重来一局功能,修复棋子可以下在计数位置的BUG。由于不明原因有时下完一局重新再来的goto出BUG了,换成了while。增加了初始页面。
2022.03.03:修复了重来后部分位置下不了棋的BUG。
2022.03.04:了解了BUG并非在goto上,换回了goto。制作了结尾页面。

#include<bits/stdc++.h>
#include<windows.h>
#include<stdio.h>
#include<conio.h>
#include<time.h>
using namespace std;
const int SIDE=20;
int nowx,nowy,mapp[SIDE][SIDE];
int Bcnt,Wcnt;char now;
POINT Windowpos(){
    POINT pt;GetCursorPos(&pt);
    HWND h=GetForegroundWindow();ScreenToClient(h,&pt);
    pt.x>>=4;pt.y>>=4;pt.x++;pt.y++;return pt;
}
void PutChar(int x,int y){
    if(x==1){if(y==1) cout<<"┏";else if(y==15) cout<<"┓";else cout<<"┳";}
    else if(x==15){if(y==1) cout<<"┗";else if(y==15) cout<<"┛";else cout<<"┻";}
    else{if(y==1) cout<<"┣";else if(y==15) cout<<"┫";else cout<<"╋";}
}
void SetPos(int x,int y){
    COORD pos;pos.X=--y<<1,pos.Y=--x;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
void MakeMap(){
    for(int i=1;i<=15;i++)
        for(int j=1;j<=15;j++)
            SetPos(i,j),PutChar(i,j);
}
void MakeStart(){
    SetPos(1,1);cout<<"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓";
    SetPos(2,1);cout<<"┃         五子棋游戏        ┃";
    SetPos(3,1);cout<<"┃大家都会玩的五子棋游戏。 一┃";
    SetPos(4,1);cout<<"┃方为黑,一方为白,黑先下。 ┃";
    SetPos(5,1);cout<<"┃自已的五颗棋子连成一条线, ┃";
    SetPos(6,1);cout<<"┃并且连成的棋子中间不能有对 ┃";
    SetPos(7,1);cout<<"┃方的棋子,就可以获胜。连成 ┃";
    SetPos(8,1);cout<<"┃的一条线可以是横着的,可以 ┃";
    SetPos(9,1);cout<<"┃是竖着的,也可以是斜着的。 ┃";
    SetPos(10,1);cout<<"┃                           ┃";
    SetPos(11,1);cout<<"┃游戏开始后,鼠标放到下棋的 ┃";
    SetPos(12,1);cout<<"┃的位置按下空格即可下棋。如 ┃";
    SetPos(13,1);cout<<"┃果任意一方胜利或平局将会显 ┃";
    SetPos(14,1);cout<<"┃示结果页面2秒然后再来一局。┃";
    SetPos(15,1);cout<<"┃                           ┃";
    SetPos(16,1);cout<<"┃     按下任意键开始游戏    ┃";
    SetPos(17,1);cout<<"┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛";
}
void MakeEnd(){
    SetPos(1,1);cout<<"┏";
    SetPos(1,15);cout<<"┓";
    SetPos(17,1);cout<<"┗";
    SetPos(17,15);cout<<"┛";
    for(int i=2;i<=14;i++){
        SetPos(1,i);cout<<"━";
        SetPos(17,i);cout<<"━";
    }
    for(int i=2;i<=16;i++){
        SetPos(i,1);cout<<"┃";
        SetPos(i,15);cout<<"┃";
    }
    if(now=='D'){SetPos(9,7);cout<<" 平局 ";}
    if(now=='B'){SetPos(9,7);cout<<"黑胜利";}
    if(now=='W'){SetPos(9,7);cout<<"白胜利";}
}
void PrintCnt(){
    SetPos(16,1);cout<<"黑棋数量:"<<Bcnt;
    SetPos(16,8);cout<<"白棋数量:"<<Wcnt;
    SetPos(17,1);cout<<"棋子总数量:"<<Bcnt+Wcnt;
}
bool CanPut(int x,int y){
    return mapp[x][y]!='B'&&mapp[x][y]!='W'&&x<=15;
}
bool CanWin(char c,int x,int y){
    if(mapp[x-4][y]==c&&mapp[x-3][y]==c&&mapp[x-2][y]==c&&mapp[x-1][y]==c) return true;
    if(mapp[x-3][y]==c&&mapp[x-2][y]==c&&mapp[x-1][y]==c&&mapp[x+1][y]==c) return true;
    if(mapp[x-2][y]==c&&mapp[x-1][y]==c&&mapp[x+1][y]==c&&mapp[x+2][y]==c) return true;
    if(mapp[x-1][y]==c&&mapp[x+1][y]==c&&mapp[x+2][y]==c&&mapp[x+3][y]==c) return true;
    if(mapp[x+1][y]==c&&mapp[x+2][y]==c&&mapp[x+3][y]==c&&mapp[x+4][y]==c) return true;
    if(mapp[x][y-4]==c&&mapp[x][y-3]==c&&mapp[x][y-2]==c&&mapp[x][y-1]==c) return true;
    if(mapp[x][y-3]==c&&mapp[x][y-2]==c&&mapp[x][y-1]==c&&mapp[x][y+1]==c) return true;
    if(mapp[x][y-2]==c&&mapp[x][y-1]==c&&mapp[x][y+1]==c&&mapp[x][y+2]==c) return true;
    if(mapp[x][y-1]==c&&mapp[x][y+1]==c&&mapp[x][y+2]==c&&mapp[x][y+3]==c) return true;
    if(mapp[x][y+1]==c&&mapp[x][y+2]==c&&mapp[x][y+3]==c&&mapp[x][y+4]==c) return true;
    if(mapp[x-4][y-4]==c&&mapp[x-3][y-3]==c&&mapp[x-2][y-2]==c&&mapp[x-1][y-1]==c) return true;
    if(mapp[x-3][y-3]==c&&mapp[x-2][y-2]==c&&mapp[x-1][y-1]==c&&mapp[x+1][y+1]==c) return true;
    if(mapp[x-2][y-2]==c&&mapp[x-1][y-1]==c&&mapp[x+1][y+1]==c&&mapp[x+2][y+2]==c) return true;
    if(mapp[x-1][y-1]==c&&mapp[x+1][y+1]==c&&mapp[x+2][y+2]==c&&mapp[x+3][y+3]==c) return true;
    if(mapp[x+1][y+1]==c&&mapp[x+2][y+2]==c&&mapp[x+3][y+3]==c&&mapp[x+4][y+4]==c) return true;
    if(mapp[x+4][y-4]==c&&mapp[x+3][y-3]==c&&mapp[x+2][y-2]==c&&mapp[x+1][y-1]==c) return true;
    if(mapp[x+3][y-3]==c&&mapp[x+2][y-2]==c&&mapp[x+1][y-1]==c&&mapp[x-1][y+1]==c) return true;
    if(mapp[x+2][y-2]==c&&mapp[x+1][y-1]==c&&mapp[x-1][y+1]==c&&mapp[x-2][y+2]==c) return true;
    if(mapp[x+1][y-1]==c&&mapp[x-1][y+1]==c&&mapp[x-2][y+2]==c&&mapp[x-3][y+3]==c) return true;
    if(mapp[x-1][y+1]==c&&mapp[x-2][y+2]==c&&mapp[x-3][y+3]==c&&mapp[x-4][y+4]==c) return true;
    return false;
}
int main(){
    system("mode con cols=30 lines=17");
    CONSOLE_CURSOR_INFO cursor_info={true,false}; 
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
    MakeStart();while(!kbhit()){}system("cls");
    St:MakeMap();system("color 60");memset(mapp,0,sizeof(mapp));
    Bcnt=Wcnt=0;now='B';PrintCnt();Sleep(500);
    while(true){
         if(GetAsyncKeyState(VK_SPACE)&0x8000){
            nowx=Windowpos().y,nowy=Windowpos().x;
              if(CanPut(nowx,nowy)){
                  SetPos(nowx,nowy);
                  now=='B'?cout<<"●":cout<<"○";
                  mapp[nowx][nowy]=now;
                  if(CanWin(now,nowx,nowy)) break;
                  now=='B'?Bcnt++:Wcnt++;PrintCnt();
                 now=='B'?now='W':now='B';
            }
             Sleep(500);
        }
         if(GetAsyncKeyState('R')&0x8000) break;
         if(Bcnt+Wcnt==225){now='D';break;}
    }
    Sleep(500);system("cls");system("color 07");
    MakeEnd();Sleep(2000);system("cls");
    goto St;
    return 0;
}