AI_会玩“猜数字游戏”的AI

/*
 *游戏规则:
 *庄家指定4个不同的数,要考虑排列次序,如 8240
 *玩家有 max_try 次猜测机会,
 *比如玩家猜 0123 , 则庄家反馈的信息是 2A0B
 *2A0B表示 指定数 有两个数在 0123 中
 *0B表示 2个出现的数 中 0个排在正确位置上
 *如果玩家猜 1234 , 则庄家反馈的信息是 1A1B
 *1A1B表示 指定数 有 1+1=2 个数在 1234 中
 *1B表示 2个出现的数 中 1个排在正确位置上
 */
#include "iostream.h"
#include "iomanip.h"
#include "string.h"
#include "stdlib.h"
#include "time.h"

//game类
#define GS_WIN 0
#define GS_TRYAGAIN 1
#define GS_FAILURE 2
#define max_try 8
class game
{
public:
 //常数
 game( const char name[] );
 void Init();
 int guess( int num[] , int &valueOk , int &placeOk );
private:
 int numbers[4];
 int guessTime;

 char player[256];

};

//
//game类的构造函数
game::game( const char name[] )
{
 strcpy( player , name );

 Init();
}
//
//Init()新游戏的初始化
void game::Init()
{
 guessTime = 0;
 srand( time(NULL) );
 for( int i = 0 ; i < 4 ; i++ )
 {
  //生成4个不相同的数
  bool flag;
  do
  {
   numbers[i] = rand() % 10;
   flag = true;
   for( int j = 0 ; j < i && flag ; j++ )
   {
    if( numbers[i] == numbers[j] )
     flag = false;
   }
  }while( !flag );
 }
}
//guess()猜
int game::guess( int num[] , int &valueOk , int &placeOk )
{
 int i , j;
 char msg[256];

 valueOk = 0;
 placeOk = 0;
 for( i = 0 ; i < 4 ; i++ )
 {
  j = 0;
  while( numbers[j] != num[i] && j < 4 )
   j++;
  if( j < 4 )
  {
   valueOk++;
  }
 }
 for( i = 0 ; i < 4 ; i++ )
 {
  if( numbers[i] == num[i] )
   placeOk++;
 }
 valueOk -= placeOk;
 
 if( guessTime == 0 )
 {
  cout<<setw(20)<<player<<setw(20)<<"GUESS"<<endl;
  cout<<"============================================================"<<endl;
 }
 for( i = 0 ; i < 4 ; i++ )
  msg[i] = num[i] + '0';
 msg[i] = 0;
 cout<<setw(20)<<msg;

 msg[0] = valueOk + '0';
 msg[1] = 'A';
 msg[2] = placeOk + '0';
 msg[3] = 'B';
 msg[4] = 0;
 cout<<setw(20)<<msg<<endl;

 guessTime++;

 for( i = 0 ; i < 4 ; i++ )
  msg[i] = numbers[i] + '0';
 msg[i] = 0;
 if( guessTime == max_try )
 {
  Init();

  cout<<"============================================================"<<endl;
  cout<<"the numbers are: "<<msg<<endl;

  if( placeOk == 4 )
  {
   cout<<"You win!"<<endl;
   return GS_WIN;
  }
  else
  {
   cout<<"You lost!"<<endl;
   return GS_FAILURE;
  }

 }
 else
 {
  if( placeOk == 4 )
  {
   cout<<"============================================================"<<endl;
   cout<<"the numbers are: "<<msg<<endl;

   cout<<"You win!"<<endl;
   Init();
   return GS_WIN;
  }
  else
  {
   return GS_TRYAGAIN;
  }
 }
 return GS_TRYAGAIN;
}
// class game end

//AI类
class xiaoAI
{
public:
 xiaoAI( const char name[] );
 ~xiaoAI();
 int play();
 void run();
private:
 void guess( int src[] , int num[] , int &valueOk , int &placeOk );
 game *mygame;
};
//
xiaoAI::xiaoAI( const char name[] )
{
 mygame = new game( name );
}
xiaoAI::~xiaoAI()
{
 delete mygame;
}
//在AI中模拟游戏过程
//
void xiaoAI::guess( int src[] , int num[] , int &valueOk , int &placeOk )
{
 int i , j;
 valueOk = 0;
 placeOk = 0;
 for( i = 0 ; i < 4 ; i++ )
 {
  j = 0;
  while( src[j] != num[i] && j < 4 )
   j++;
  if( j < 4 )
  {
   valueOk++;
  }
 }
 for( i = 0 ; i < 4 ; i++ )
 {
  if( src[i] == num[i] )
   placeOk++;
 }
 valueOk -= placeOk;
}
//

int xiaoAI::play()
{
 int num[4];
 int src[4];
 int result[7][2];
 int ret[7][2];

 int answer[1024][4];
 int answerNum = 0;

 int a , b , c , d;
 int i , j , k;

 //用 0123 1234 2345 ... 5678 猜6次
 //得到的结果保存在 result[i] 中
 for( i = 0 ; i < max_try - 1 ; i++ )
 {
  for( j = 0 ; j < 4 ; j++ )
   num[j] = i + j;
  int ret = mygame->guess( num , result[i][0] , result[i][1] );
  if( ret == GS_WIN )
  {
   return GS_WIN;
  }
 }
 // 假如游戏中生成的4个数字为a,b,c,d
 // 穷举所有 a,b,c,d 可能的组合
 // 测试在这种组合下, 以 0123 1234 ... 5678 猜测应得的结果
 // 如果应得结果与所得结果相符
 // 则这种组合是可能的正确答案
 // 如果有多种可能组合,则 以等概率 随机猜测
 for( a = 0 ; a < 10 ; a++ )
 for( b = 0 ; b < 10 ; b++ )
 if( a != b )
 for( c = 0 ; c < 10 ; c++ )
 if( a != c && b != c )
 for( d = 0 ; d < 10 ; d++ )
 if( a != d && b != d && c != d )
 {
  src[0] = a;
  src[1] = b;
  src[2] = c;
  src[3] = d;

  bool flag = true;
  i = 0;
  while( flag && i < max_try - 1 )
  {
   for( j = 0 ; j < 4 ; j++ )
    num[j] = i + j;
   guess( src , num , ret[i][0] , ret[i][1] );
   flag = true;
   if( ret[i][0] != result[i][0] || ret[i][1] != result[i][1] )
    flag = false;
   i++;
  }
  if( flag )
  {
   for( i = 0 ; i < 4 ; i++ )
    answer[answerNum][i] = src[i];
   answerNum++;
  }
 }
 //
 if( answerNum < 1 )
 {
  //如果找不到可能的组合,则生成随机的4个数
  //事实上,一定能找到
  //因为上述操作是穷举所有可能组合
  cout<<"i don't know the answer."<<endl;
  cout<<"i guess ..."<<endl;
  for( int i = 0 ; i < 4 ; i++ )
  {
   //生成4个不相同的数
   bool flag;
   do
   {
    num[i] = rand() % 10;
    flag = true;
    for( int j = 0 ; j < i && flag ; j++ )
    {
     if( num[i] == num[j] )
      flag = false;
    }
   }while( !flag );
  }
  mygame->guess( num , i , j );
 }
 else
 {
  if( answerNum > 1 )
  {
   cout<<"there are "<<answerNum<<" possible."<<endl;
   for( i = 0 ; i < answerNum ; i++ )
   {
    for( j = 0 ; j < 4 ; j++ )
     cout<<answer[i][j];
    cout<<endl;
   }
   cout<<"my choice..."<<endl;
  }
  k = rand() % answerNum;
  k = mygame->guess( answer[k] , i , j );
 }
 return k;
}
//
void xiaoAI::run()
{
 do
 {
  play();
  cin.get();
  for( int i = 0 ; i < 80 ; i++ )
   cout<<endl;
 }while( 1 );
}
//AI end


void main()
{
 xiaoAI ice( "zeroDspace" );
 ice.run();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值