题目:编写一个"人机对弈"的下棋程序,四个棋子连成一线即为赢。人走棋的合法输入为0-6。棋盘是垂直放置,棋子落到底部。
说明:这个程序可以选择是计算机先走还是人先走,我们的作业不要求这样,固定为人先走,计算机后走即可
程序结构可以参考如下结构,也可以按自己思路。
class game//这是个抽象类,抽象的是所有人走一步,计算机走一步的对弈游戏
{
public:
enum who { HUMAN, NEUTRAL, COMPUTER };
game( ) { move_number = 0; }
virtual ~game( ) { }
who play( ); //人先走,计算机后走,返回值是游戏的赢者,后面给出了此函数的定义
protected:
//以下虚函数可以被覆盖,也可以不被覆盖
virtual void display_message(const string& message)const;//在屏幕显示信息message
virtual int get_user_move( )const; // 输出"Your move,please:",然后接受用户输入,并将输入返回
virtual who last_mover( ) const
{ return (move_number % 2 == 1 ? HUMAN : COMPUTER); }
virtual int moves_completed( ) const { return move_number; }
virtual who next_mover( ) const
{ return (move_number % 2 == 0 ? HUMAN : COMPUTER); }
// 以下虚函数必须被覆盖
virtual void make_move(const int& move)//将棋子真正下到棋盘上,此函数被子类覆盖
{ ++move_number; }
virtual void restart( ) { move_number = 0; }//开始新的棋局
//以下为纯虚函数
virtual who winning( )const =0; //返回胜利者
virtual void display_status( ) = 0; //显示游戏棋盘的当前状态
virtual bool is_game_over( ) = 0; //如果游戏结束,返回真
virtual bool is_legal(const int& move) = 0; //如果给定走法为合法,就返回真
virtual void make_computer_move( )=0; //计算计算机所有的可能的走法,选出一种最好的,并调用make_move(best_move)
private:
int move_number; //当前已走的步数
void make_human_move( ); //调用 get_user_move( ),并用is_legal(move)判断是否合法输入,若是则调用make_move(move)
};
class c4 : public game//这个类是我们具体要实现的“四子棋”
{
public:
c4( ) {restart( );}
protected:
virtual void make_move(const int& move); // 修改data[][],many_used[]和most_recent_column的值,并调用game::make_move(move)
virtual void restart( ); //将data[6][7]各元素置为NEUTRAL,将many_used[7]各元素置为0 ,再调用game::restart();
virtual game::who winning( )const ;
virtual void display_status( ) ; //显示棋盘的状态
virtual bool is_game_over( ) ;
virtual bool is_legal(const int& move) ;
virtual void make_computer_move( );
private:
who data[6][7]; //6行7列,表示棋盘
int many_used[7]; //表示各列中已有多少个棋子
int most_recent_column; //最近下的棋子在哪列
};
//人先走,计算机后走,返回值是游戏的赢者
game::who game::play()
{
restart();
while(!is_game_over())
{
display_status();
if(last_mover()==COMPUTER)
make_human_move();
else
make_computer_move();
}
display_status();
return winning();
}
void main()
{
c4 instance;
game::who winner;
winner=instance.play();
switch(winner)
{
case c4::HUMAN: cout<<"You win!"<<endl;break;
case c4::COMPUTER: cout<<"I win!"<<endl;break;
case c4::NEUTRAL: cout<<"A draw"<<endl;break;
}
}
实现代码:
#include<iostream>
#include<ctime>
using namespace std;
class game
{
public:
int move_number;
enum who { HUMAN, NEUTRAL, COMPUTER};
game( ) { move_number = 0; }
virtual ~game( ) { };
who play( );
protected:
virtual int get_user_move( )const;
virtual who last_mover( ) const
{ return (move_number % 2 == 1 ? HUMAN : COMPUTER); }
virtual int moves_completed( ) const { return move_number; }
virtual who next_mover( ) const
{ return (move_number % 2 == 0 ? HUMAN : COMPUTER); }
virtual void make_move(const int& move)
{ ++move_number; }
virtual void restart( ) { move_number = 0; }
virtual who winning( )const =0;
virtual void display_status( ) = 0;
virtual bool is_game_over( ) = 0;
virtual bool is_legal(const int& move) = 0;
virtual void make_computer_move( )=0;
private:
void make_human_move( );
};
int game::get_user_move()const
{ int step;
cout<<"Your move,please:";
cin>>step;
return step;
}
void game::make_human_move()
{ int step;
step=get_user_move();
if(is_legal(step))
make_move(step);
else
{cout<<"The move is illegal!"<<endl;
make_human_move();
}
}
class c4 : public game
{
public:
c4( ) {restart( );}
protected:
virtual void make_move(const int& move);
virtual void restart( );
virtual game::who winning( )const ;
virtual void display_status( ) ;
virtual bool is_game_over( ) ;
virtual bool is_legal(const int& move) ;
virtual void make_computer_move( );
bool if_two();
bool if_three();
private:
who data[6][7];
int many_used[7];
int most_recent_column;
};
bool c4::is_game_over()
{int i,j;
if(move_number==42) return true;
for(i=0;i<6;++i)
{
for(j=0;j<4;++j)
{
if(data[i][j]!=NEUTRAL&&data[i][j]==data[i][j+1]&&data[i][j]==data[i][j+2]&&data[i][j]==data[i][j+3])
return true;
}
}
for(i=0;i<3;++i)
{
for(j=0;j<7;++j)
{
if(data[i][j]!=NEUTRAL&&data[i][j]==data[i+1][j]&&data[i][j]==data[i+2][j]&&data[i][j]==data[i+3][j])
return true;
}
}
for(i=0;i<3;++i)
{
for(j=0;j<4;++j)
{
if(data[i][j]!=NEUTRAL&&data[i][j]==data[i+1][j+1]&&data[i][j]==data[i+2][j+2]&&data[i][j]==data[i+3][j+3])
return true;
}
}
for(i=0;i<3;++i)
{
for(j=6;j>2;--j)
{
if(data[i][j]!=NEUTRAL&&data[i][j]==data[i+1][j-1]&&data[i][j]==data[i+2][j-2]&&data[i][j]==data[i+3][j-3])
return true;
}
}
return false;
}
bool c4::if_two()
{
int i,j;
for(i=0;i<6;++i)
{
for(j=0;j<6;++j)
{
if(data[i][j]!=NEUTRAL&&data[i][j]==data[i][j+1])
return true;
}
}
for(i=0;i<5;++i)
{
for(j=0;j<7;++j)
{
if(data[i][j]!=NEUTRAL&&data[i][j]==data[i+1][j])
return true;
}
}
for(i=0;i<5;++i)
{
for(j=0;j<6;++j)
{
if(data[i][j]!=NEUTRAL&&data[i][j]==data[i+1][j+1])
return true;
}
}
for(i=0;i<5;++i)
{
for(j=6;j>0;--j)
{
if(data[i][j]!=NEUTRAL&&data[i][j]==data[i+1][j-1])
return true;
}
}
return false;
}
bool c4::if_three()
{
int i,j;
for(i=0;i<6;++i)
{
for(j=0;j<5;++j)
{
if(data[i][j]!=NEUTRAL&&data[i][j]==data[i][j+1]&&data[i][j]==data[i][j+2])
return true;
}
}
for(i=0;i<4;++i)
{
for(j=0;j<7;++j)
{
if(data[i][j]!=NEUTRAL&&data[i][j]==data[i+1][j]&&data[i][j]==data[i+2][j])
return true;
}
}
for(i=0;i<4;++i)
{
for(j=0;j<5;++j)
{
if(data[i][j]!=NEUTRAL&&data[i][j]==data[i+1][j+1]&&data[i][j]==data[i+2][j+2])
return true;
}
}
for(i=0;i<4;++i)
{
for(j=6;j>0;--j)
{
if(data[i][j]!=NEUTRAL&&data[i][j]==data[i+1][j-1]&&data[i][j]==data[i+2][j-2])
return true;
}
}
return false;
}
bool c4::is_legal(const int& move)
{
if(many_used[move]<6&&move>=0&&move<7)
return true;
else
return false;
}
game::who c4::winning()const
{
if(move_number==6*7)
return NEUTRAL;
else
return game::last_mover();
}
void c4::make_computer_move()
{
if(move_number==1)
{
while(rand()>=6)
{
most_recent_column=rand()%6;
}
make_move(most_recent_column);
return ;
}
int i,mark;
int move,score[7],max_score=0,best_move=0;
for(i=0;i<7;i++)
{
score[i]=0;
}
for(move=0;move<7;move++)
{
if(many_used[move]<6)
{
data[5-many_used[move]][move]=COMPUTER;
if(is_game_over()&&is_legal(move))
{
make_move(move);
return ;
}
data[5-many_used[move]][move]=NEUTRAL;
}
}
for(move=0;move<7;move++)
{
if(many_used[move]<6)
{
data[5-many_used[move]][move]=HUMAN;
if(is_game_over()&&is_legal(move))
{
make_move(move);
return ;
}
data[5-many_used[move]][move]=NEUTRAL;
}
}
for(move=0;move<7;move++)
{
if(is_legal(move))
{
data[5-many_used[move]][move]=HUMAN;
if(if_three())
{
mark=5;
if(mark>score[move])
score[move]=mark;
}
data[5-many_used[move]][move]=NEUTRAL;
}
else
continue;
}
for(move=0;move<7;move++)
{
if(is_legal(move))
{
data[5-many_used[move]][move]=COMPUTER;
if(if_three())
{
mark=4;
if(mark>score[move])
score[move]=mark;
}
data[5-many_used[move]][move]=NEUTRAL;
}
else
continue;
}
for(move=0;move<7;move++)
{
if(is_legal(move))
{
data[5-many_used[move]][move]=HUMAN;
if(if_two())
{
mark=3;
if(mark>score[move])
score[move]=mark;
}
data[5-many_used[move]][move]=NEUTRAL;
}
else
continue;
}
for(move=0;move<7;move++)
{
if(is_legal(move))
{
data[5-many_used[move]][move]=COMPUTER;
if(if_two())
{
mark=2;
if(mark>score[move])
score[move]=mark;
}
data[5-many_used[move]][move]=NEUTRAL;
}
else
continue;
}
for(i=0;i<7;i++)
if(max_score<=score[i])
{
best_move=i;
max_score=score[i];
}
make_move(best_move);
}
void c4::make_move(const int& move)
{
most_recent_column=move;
if(next_mover()==HUMAN)
{
data[5-many_used[move]][move]=HUMAN;
}
else
{
data[5-many_used[move]][move]=COMPUTER;
}
many_used[move]++;
game::make_move(move);
}
void c4::display_status()
{
int i,j;
for(i=0;i<6;i++)
{
cout<<" ";
for(j=0;j<7;j++)
{if(data[i][j]==HUMAN)
cout<<" "<<"*";
else if(data[i][j]==COMPUTER)
cout<<" "<<"#";
else
cout<<" "<<".";
}
cout<<endl;
}
cout<<" ___________________"<<endl;
cout<<" 0 1 2 3 4 5 6"<<endl;
cout<<" Human:* Computer:#"<<endl;
cout<<"当前各列棋子数分别为:";
for(i=0;i<7;i++)
cout<<" "<<many_used[i];
cout<<endl;
cout<<"当前已经走的步数:"<<move_number<<endl;
}
void c4::restart()
{
int i,j;
for(i=0;i<6;++i)
{
for(j=0;j<7;++j)
{
data[i][j]=NEUTRAL;
many_used[j]=0;
}
}
game::restart();
}
game::who game::play()
{
restart();
while(!is_game_over())
{
display_status();
if(last_mover()==COMPUTER)
make_human_move();
else
make_computer_move();
}
display_status();
return winning();
}
void main()
{
srand((unsigned int)time(NULL));
c4 instance;
game::who winner;
winner=instance.play();
switch(winner)
{
case c4::HUMAN: cout<<"You win!"<<endl;break;
case c4::COMPUTER: cout<<"Sorry,the computer win."<<endl;break;
case c4::NEUTRAL: cout<<"A draw"<<endl;break;
}
}
运行结果: