五子棋c++实现

0x00

“c++不可不学”——鲁迅

    代码不包含ai,包含评估函数,带悔棋

main.cpp

#include "chess.h"
#include "std_facilities.h"
int main(){
	Chess s;
	int x=0,y=0;
	while(true){
		Step next=s.who_is_next();
		s.print();
		cout<<"next is "<<((next==BLACK)?"black":"white")<<'\n';
		cout<<">";
		cin>>x>>y;
		if(x==y&&x==15){
			s.regret();
		}
		else{
			s.put(x,y);
			cout<<"after this step,you value is "<<s.get_value(next)<<'\n';	
		}
		
	}
	return 0;
}

chess.h

#pragma once
#include "std_facilities.h"
enum Step{
	BLANK,
	BLACK,
	WHITE
};
class Chess{
public:
	Chess();
	void put(int x,int y);
	int get_value(Step s);
	void print();
	Step who_is_next();
	void regret();
private:
	Step* map;
	vector<int> history;
	Step next;
	Step get(int x,int y);
	void go_back();
};

chess.cpp

#include "std_facilities.h"
#include "chess.h"
const int WIDTH=15;
Chess::Chess(){
	next=BLACK;
	map=new Step[WIDTH*WIDTH];
}
Step Chess::get(int x,int y){
	return map[x*15+y];
}
Step Chess::who_is_next(){
	return next;
}
void Chess::regret(){
	go_back();
	go_back();
}
void Chess::go_back(){
	int pos=history[history.size()-1];
	map[pos]=BLANK;
	history.pop_back();
}
void Chess::put(int x,int y){
	if(get(x,y)!=BLANK) error("此处已有棋子!\n");
	map[x*15+y]=next;
	history.push_back(x*15+y);
	if(next==BLACK) next=WHITE;
	else if(next==WHITE) next=BLACK;
}
int Chess::get_value(Step s){
	int ret=0;
	Step other;
	if(s==BLACK) other=WHITE;
	else if(s==WHITE) other=BLACK;
	int left=-1;
	int cnt=0;
	int left1=-1;
	int cnt1=0;
	int pos1=0;
	int pos2=0;
	int pos=0;
	for(int x=0;x<WIDTH;x++){
		left=-1;
		cnt=0;
		left1=-1;
		cnt1=0;
		pos1=0;
		pos2=0;
		for(int y=0;y<WIDTH;y++){
			pos=x*15+y;
			
			if(map[pos]==other){
				if(cnt==0){
					cnt++;
					left=y;
					pos1=x*15+left;
				}else{
					cnt++;
					if(cnt==4&&((left-1>=0&&map[pos1-1]==BLANK)||(y+1<WIDTH&&map[pos+1]!=s)     ))
					{
						ret=-10000;
						return 	ret;		
					}
				}
			}else{
				cnt=0;
			}
			if(map[pos]==s){
				if(cnt1==0){
					cnt1++;
					left1=y;
					pos2=x*15+left1;
				}else{
					cnt1++;
					if(cnt1==4&&(  (left1-1>=0&&map[pos2-1]==BLANK) && (y+1<WIDTH&&map[pos+1]==BLANK) )){
						ret=1000;
					}
					if(cnt1==5) ret=10000;
				}
			}else{
				cnt1=0;
			}
		}
	}
	for(int y=0;y<WIDTH;y++){
		cnt=0;
		cnt1=0;
		left=-1;
		left1=-1;
		pos1=0;
		pos2=0;
		for(int x=0;x<WIDTH;x++){
			pos=x*15+y;
			
			if(map[pos]==other){
				if(cnt==0){
					cnt++;
					left=x;
					pos1=left*15+y;
				}else{
					cnt++;
					if(cnt==4&&((left-1>=0&&map[pos1-15]==BLANK)||(x+1<WIDTH&&map[pos+15]!=s)     ))
					{
						ret=-10000;
						return 	ret;		
					}
				}
			}else{
				cnt=0;
			}
			if(map[pos]==s){
				if(cnt1==0){
					cnt1++;
					left1=x;
					pos2=left1*15+y;
				}else{
					cnt1++;
					if(cnt1==4&&(  (left1-1>=0&&map[pos2-15]==BLANK) && (x+1<WIDTH&&map[pos+15]==BLANK) )){
						ret=1000;
					}
					if(cnt1==5) ret=10000;
				}
			}else{
				cnt1=0;
			}
		}
	}
	for(int x=0;x<WIDTH*2-1;x++){
		cnt=0;
		cnt1=0;
		left=-1;
		left1=-1;
		pos1=0;
		pos2=0;
		if(x<WIDTH){
			for(int y=0;y<=x;y++){
				pos=(x-y)*15+y;
				
				if(map[pos]==other){
					if(cnt==0){
						cnt++;
						left=y;
						pos1=(x-left)*15+left;
					}else{
						cnt++;
						if(cnt==4&&(((left-1>=0)&&map[pos1+14]==BLANK)||(y+1<=x&&map[pos-14]!=s)     ))
						{
							ret=-10000;
							return 	ret;		
						}
					}
				}else{
					cnt=0;
				}
				if(map[pos]==s){
					if(cnt1==0){
						cnt1++;
						left1=y;
						pos2=(x-left1)*15+left1;
					}else{
						cnt1++;
						if(cnt1==4&&(  (left1-1>=0&&map[pos2+14]==BLANK) && (y+1<=x&&map[pos-14]==BLANK) )){
							ret=1000;
						}
						if(cnt1==5) ret=10000;
					}
				}else{
					cnt1=0;
				}
			}
		}else{
			for(int y=0;y<WIDTH*2-1-x;y++){
				pos=(WIDTH-1-y)*15+y+x-WIDTH+1;
				
				if(map[pos]==other){
					if(cnt==0){
						cnt++;
						left=y;
						pos1=(WIDTH-1-left)*15+left+x-WIDTH+1;
					}else{
						cnt++;
						if(cnt==4&&(((y-1>=0)&&map[pos1+14]==BLANK)||(y+1<WIDTH*2-1-x&&map[pos-14]!=s)     ))
						{
							ret=-10000;
							return 	ret;		
						}
					}
				}else{
					cnt=0;
				}
				if(map[pos]==s){
					if(cnt1==0){
						cnt1++;
						left1=y;
						pos2=(WIDTH-1-left1)*15+left1+x-WIDTH+1;
					}else{
						cnt1++;
						if(cnt1==4&&(  (left1-1>=0&&map[pos2+14]==BLANK) && (y+1<WIDTH*2-1-x&&map[pos-14]==BLANK) )){
							ret=1000;
						}
						if(cnt1==5) ret=10000;
					}
				}else{
					cnt1=0;
				}
			}
		}
	}
	//下面这段代码有bug
	for(int x=0;x<WIDTH*2-1;x++){
		cnt=0;
		cnt1=0;
		left=-1;
		left1=-1;
		pos1=0;
		pos2=0;
		if(x<WIDTH){
			for(int y=0;y<=x;y++){
				pos=(WIDTH-1-y)*15+x-y;
				
				if(map[pos]==other){
					if(cnt==0){
						cnt++;
						left=y;
						//cout<<"other y:"<<left<<'\n';
						pos1=(WIDTH-1-left)*15+x-left;
					}else{
						cnt++;
						if(cnt==4&&(((left-1>=0)&&map[pos1+16]==BLANK)||(y+1<=x&&map[pos-16]!=s)))
						{
							ret=-10000;
							return 	ret;		
						}
					}
				}else{
					cnt=0;
				}
				if(map[pos]==s){
					if(cnt1==0){
						cnt1++;
						left1=y;
						pos2=(WIDTH-1-left1)*15+x-left1;
					}else{
						cnt1++;
						if(cnt1==4&&(  (left1-1>=0&&map[pos2+16]==BLANK) && (y+1<=x&&map[pos-16]==BLANK) )){
							ret=1000;
						}
						if(cnt1==5) ret=10000;
					}
				}else{
					cnt1=0;
				}
			}
		}else{
			for(int y=0;y<WIDTH*2-1-x;y++){
				pos=(WIDTH*2-2-x-y)*15+WIDTH-y;
				if(map[pos]==other){
					if(cnt==0){
						cnt++;
						left=y;
						pos1=(WIDTH*2-2-x-left)*15+WIDTH-left;
					}else{
						cnt++;
						if(cnt==4&&(((left-1>=0)&&map[pos1+16]==BLANK)||(y+1<WIDTH*2-1-x&&map[pos-16]!=s)     ))
						{
							ret=-10000;
							return 	ret;		
						}
					}
				}else{
					cnt=0;
				}
				if(map[pos]==s){
					if(cnt1==0){
						cnt1++;
						left1=y;
						pos2=(WIDTH*2-2-x-left1)*15+WIDTH-left1;
					}else{
						cnt1++;
						if(cnt1==4&&(  (left1-1>=0&&map[pos2+16]==BLANK) && (y+1<WIDTH*2-1-x&&map[pos-16]==BLANK) )){
							ret=1000;
						}
						if(cnt1==5) ret=10000;
					}
				}else{
					cnt1=0;
				}
			}
		}
	}
	return ret;
}
void Chess::print(){
	cout<<"  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4\n";
	cout<<"  -----------------------------\n";
	for(int x=0;x<WIDTH;x++){
		cout<<x%10;
		cout<<"|";
		for(int y=0;y<WIDTH;y++){
			switch(map[x*15+y]){
				case BLANK:
					cout<<"  ";
					break;
				case BLACK:
					cout<<"X ";
					break;
				case WHITE:
					cout<<"O ";
					break;
				default:
					error("未定义的棋子!\n");
			}
		}
		cout<<'\n';
	}
}