井字棋/五子棋双人代码
2026-08-19 15:38:02
发布于:广东
上集训营比赛AK后好无聊,就一直在写,写了3天了,终于写完了。
快点我
井字棋:
#include<bits/stdc++.h>
using namespace std;
int a[3][3],i=9,x,y;
void couta(){
cout<<" "<<a[0][0]<<" | "<<a[0][1]<<" | "<<a[0][2]<<"\n";
cout<<"---+---+---"<<"\n";
cout<<" "<<a[1][0]<<" | "<<a[1][1]<<" | "<<a[1][2]<<"\n";
cout<<"---+---+---"<<"\n";
cout<<" "<<a[2][0]<<" | "<<a[2][1]<<" | "<<a[2][2]<<"\n";
}
bool win(int x,int y){
if(a[x][0]==a[x][1]&&a[x][1]==a[x][2]&&a[x][0]!=0){
return 1;
}
if(a[0][y]==a[1][y]&&a[1][y]==a[2][y]&&a[0][y]!=0){
return 1;
}
if(a[1][1]==a[2][2]&&a[2][2]==a[0][0]&&a[1][1]!=0){
return 1;
}
if(a[0][2]==a[1][1]&&a[1][1]==a[2][0]&&a[1][1]!=0){
return 1;
}
return 0;
}
void mian(int turn){
couta();
cout<<"轮到"<<turn<<"了";
cin>>x>>y;
x--;
y--;
if(a[x][y]==0){
a[x][y]=turn;
if(win(x,y)){
cout<<turn<<"赢了\n赢了\n赢了\n赢了\n赢了\n";
return;
}
}else cout<<"不合法,跳过\n",i++;
}
int main() {
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
a[i][j]=0;
}
}
int turn=1;
while(i--){
mian(turn);
turn==1?turn=2:turn=1;
}
cout<<"平局";
return 0;
}
五子棋代码:
注:输入 99 99 是悔棋
#include<bits/stdc++.h>
using namespace std;
int x,y,lx,ly,i=19*30;
bool boo=0;
int a[50][50];
struct hq{
int x,y;
}hq[600];
string cf[3];
//判断是否越界
bool check(int x,int y){
return x>0&&y>0&&x<=19&&y<=30;
}
//如果一个人赢了,输出一行赢了
void coutwin(int turn){
for(int i=1;i<7;i++)
cout<<turn<<"赢了"<<turn<<"赢了"<<turn<<"赢了"<<turn<<"赢了"<<turn<<"赢了";
cout<<turn<<"赢了\n";
return;
}
//如果不合法,输出不合法,跳过
void illegal(){
for(int i=1;i<=100;i++){
cout<<"不合法,跳过 不合法,跳过 不合法,跳过 不合法,跳过 ";
cout<<"不合法,跳过 不合法,跳过 不合法,跳过 不合法,跳过 ";
cout<<"不合法,跳过 不合法,跳过 不合法,跳过 不合法,跳过";
}
cout<<"\n\n\n\n\n";
return;
}
//判断横着的有没有连成五个
bool hj(int x,int y){
int b[10];
for(int i=-4;i<5;i++){
if(y+i<=0&&y+i>30&&a[x][y+i]==a[x][y])b[i+4]=1;
else b[i+4]=0;
}
for(int i=0;i<=5;i++){
if(b[i]==1&&b[i]==b[i+1]&&b[i]==b[i+2]&&b[i]==b[i+3]&&b[i]==b[i+4])return 1;
}
return 0;
}
//判断竖着的有没有连成五个
bool sj(int x,int y){
int b[10];
for(int i=-4;i<5;i++){
if(x+i<=0&&x+i>19&&a[x+i][y]==a[x][y])b[i+4]=1;
else b[i+4]=0;
}
for(int i=0;i<=5;i++){
if(b[i]==1&&b[i]==b[i+1]&&b[i]==b[i+2]&&b[i]==b[i+3]&&b[i]==b[i+4])return 1;
}
return 0;
}
//判断从左上到右下斜着的有没有连成五个
bool xj1(int x,int y){
int b[10];
for(int i=-4;i<5;i++){
if(x+i<=0&&x+i>19&&y+i<=0&&y+i>30&&a[x+i][y+i]==a[x][y])b[i+4]=1;
else b[i+4]=0;
}
for(int i=0;i<=5;i++){
if(b[i]==1&&b[i]==b[i+1]&&b[i]==b[i+2]&&b[i]==b[i+3]&&b[i]==b[i+4])return 1;
}
return 0;
}
//判断从左上下到右上斜着的有没有连成五个
bool xj2(int x,int y){
int b[10];
for(int i=-4;i<5;i++){
if(x+i<=0&&x+i>19&&y-i<=0&&y-i>30&&a[x+i][y-i]==a[x][y])b[i+4]=1;
else b[i+4]=0;
}
for(int i=0;i<=5;i++){
if(b[i]==1&&b[i]==b[i+1]&&b[i]==b[i+2]&&b[i]==b[i+3]&&b[i]==b[i+4])return 1;
}
return 0;
}
void couta() {
for(int i=1;i<=30;i++){
if(i==1)cout<<" ";
cout<<" ";
printf("%02d",i);
cout<<" ";
}
cout<<"\n";
for(int i=1;i<=39;i++){
cout<<" ";
for(int j=1;j<=30;j++){
if(j==1){
if(i%2==0){
printf("%.2d",i/2);
cout<<"| ";
}else{
cout<<" +";
}
}
if(i%2==0){
if(a[i/2][j]){
if(a[i/2][j]==1){
cout<<"■";
}else cout<<"□";
}else cout<<" ";
cout<<" | ";
}else cout<<"----+";
}
cout<<"\n";
}
return;
}
void coutcf(int turn){
int a=0;
while(a<120){
cout<<turn<<":"<<cf[turn]<<" ";
a+=cf[turn].size()+1;
}
cout<<"\n";
return;
}
bool amax(){
for(int i=1;i<=19;i++){
for(int j=1;j<=30;j++){
if(a[i][j]==0)return 0;
}
}
return 1;
}
void mian(int turn){
couta();
cout<<"轮到"<<turn<<"了\n";
cin>>x>>y;
if(x==99&&y==99){
i++;
if(i==0){
cout<<"你下棋了吗你就悔 你下棋了吗你就悔 你下棋了吗你就悔 你下棋了吗你就悔 ";
cout<<"你下棋了吗你就悔 你下棋了吗你就悔 你下棋了吗你就悔 你下棋了吗你就悔 ";
cout<<"你下棋了吗你就悔\n";
return;
}
a[hq[i].x][hq[i].y]=0;
cout<<hq[i].x<<" "<<hq[i].y<<" ";
i++;
cout<<"悔棋成功 悔棋成功 悔棋成功 悔棋成功 悔棋成功 悔棋成功 悔棋成功 悔棋成功 ";
cout<<"悔棋成功 悔棋成功 悔棋成功 悔棋成功 悔棋成功 悔棋成功 悔棋成功 悔棋成功 ";
cout<<"悔棋成功\n";
return;
}
lx=x;
ly=y;
if(check(x,y)&&a[x][y]==0){
a[x][y]=turn;
hq[i].x=x;
hq[i].y=y;
cout<<hq[i-1].x<<" "<<hq[i-1].y<<" ";
if(hj(x,y)||sj(x,y)||xj1(x,y)||xj2(x,y)){
couta();
for(int i=1;i<=3;i++)coutwin(turn);
for(int i=1;i<=38;i++)coutcf(turn);
cout<<hj(x,y)<<sj(x,y)<<xj1(x,y)<<xj2(x,y);
exit(0);
}
}else illegal(),i++;
}
int main() {
bool boo=1;
while(boo){
cout<<"请输入你的嘲讽语句,要用默认的话不要在后面打空格!\n";
cout<<"1:菜就多练\n2:给我擦皮鞋\n3:都是同龄人我原本没想降维打击\n";
cout<<"也可以自己输入,输入不要空格!!!!!";
cin>>cf[1]>>cf[2];
if(cf[1]=="1"){
cf[1]="菜就多练";
}else if(cf[1]=="2"){
cf[1]="给我擦皮鞋";
}else if(cf[1]=="3"){
cf[1]="都是同龄人我原本没想降维打击";
}
if(cf[2]=="1"){
cf[2]="菜就多练";
}else if(cf[2]=="2"){
cf[2]="我擦皮鞋";
}else if(cf[2]=="3"){
cf[2]="都是同龄人我原本没想降维打击";
}
cout<<"1号是("<<cf[1]<<")\n2号是("<<cf[2]<<")\n确认吗?\n";
cout<<"如果是,输入0,如果不是,输入1\n";
cin>>boo;
}
cout<<"输入 99 99 是悔棋\n";
system("pause");
system("cls");
cout<<"\n";
for(int i=0;i<50;i++){
for(int j=0;j<50;j++){
a[i][j]=0;
}
}
int turn=1;
while(i--){
mian(turn);
if(turn==1)turn=2;
else turn=1;
}
cout<<"平局\n1:棋逢对手2:承让承让";
}
写这些东西累死我了,c++上开全屏就能玩。
五子棋加了一个悔棋
制作不易,点个赞吧求求了
全部评论 4
- 置顶
有BUG私信发我,我会改的。
5天前 来自 广东
2看不懂的也可以私信问我(应该没有人看不懂吧)
5天前 来自 广东
1没有cls
不好啊昨天 来自 浙江
0我觉得挺好的,没事我打点注释,你等会儿,我现在在上集训营
昨天 来自 广东
0

10小时前 来自 广东
1@立春男明星(关必回)胜负判定逻辑错误 (最严重)
原代码问题:hj, sj, xj1, xj2函数中,数组 b 记录的是“该位置是否与当前落子颜色相同”。然后检查 b 中是否有连续5个 1。
Bug:如果中间有空位(0),b对应位置为0。但如果棋盘上已有其他颜色的棋子,b也为0。这本身逻辑看似可行,但边界处理极其脆弱。更致命的是,原代码在检查连续5个时,只要 b[i] 到 b[i+4] 相等且为1即可。然而,由于 b 初始化为随机值(局部变量未初始化),或者逻辑中 continue 导致某些位置未被赋值,可能产生误判。
修正:标准的五子棋判定应以落子点为中心,向四个方向延伸,统计连续相同颜色的棋子数量。
悔棋逻辑缺陷原代码问题:只记录了 lx, ly(上一步的位置)。如果玩家A下错,悔棋;轮到玩家B,玩家B也下错,悔棋。此时 lx, ly 被覆盖为玩家B的位置。如果玩家A想再次悔棋(回退到玩家B下之前),原代码只能回退一步,无法连续悔棋或多步悔棋。
修正:虽然简单版只支持悔一步也可以,但原代码在 illegal() 后执行 i++ 试图补偿回合数,这与 while(i--) 循环配合得非常混乱,容易导致回合错乱。
输入缓冲与交互问题原代码问题:getline 读取嘲讽语句后,如果没有正确处理换行符,后续的 cin >> x >> y 可能会读取到残留的换行符或导致跳过输入。
修正:在混合使用 getline 和 cin 时需要小心清理缓冲区。
棋盘显示与坐标系统原代码问题:棋盘大小定义为 19*30?通常五子棋是 15x15 或 19x19。代码中 check 函数限制 x<=19, y<=30,这是一个非标准的长方形棋盘,视觉上会很奇怪。
修正:建议统一为标准 15x15 或 19x19 正方形棋盘。
全局变量滥用i 用作循环计数器又是全局变量,且在 mian 中被修改,极易出错。
13小时前 来自 广东
1nb
12小时前 来自 广东
0但是一般都是从中间下的啊,所以没啥事
9小时前 来自 广东
0

























有帮助,赞一个