游戏简介
三连棋游戏(两人轮流在印有九格方盘上划“+”或“O”字, 谁先把三个同一记号排成横线、直线、斜线, 即是胜者)。
程序提供随机算法和智能算法两种AI,随机算法使用随机数随意选择棋盘上的位置,智能算法通过对每隔落子位置权重的计算,选取最优的落子点。
游戏实现
#include <iostream>
#include <vector>
#include <ctime>
#include <string>
using namespace std;
//human takes X, Competitor takes O,
enum Checker{
EMPTY, X, O
};
//base class of RandomAI, intermediateAI, Human
class Competitor{
public:
//use move to avoid copy
Competitor(Checker type, string name):checkerType(type), name(move(name)){
}
virtual ~Competitor(){}
//Competitor algorithms : random and intermediateAI
virtual void desiredMove(vector<vector<Checker>> &checkBoard, Checker type) = 0;
//checker type
Checker checkerType;
string name;
};
//move checker by random seed
class RandomAI:public Competitor{
public:
RandomAI():Competitor(O,"RandomAI"){
srand((unsigned int) time(nullptr));
}
void desiredMove(vector<vector<Checker>> &checkBoard, Checker type)override{
checkerType = type;
//traversing the whole board, get empty checker number
int emptyCheckerNum = 0;
for(auto &row: checkBoard){
for(auto &checker: row){
if(checker == EMPTY){
emptyCheckerNum++;
}
}
}
if(emptyCheckerNum == 0)
return;
//get random index
int randomIndex = rand()%(emptyCheckerNum) + 1;
emptyCheckerNum = 0;
for(auto &row: checkBoard){
for(auto &checker: row){
if(checker == EMPTY){
if(++emptyCheckerNum == randomIndex){
checker = checkerType;
return;
}
}
}
}
cout<<"RandomAI move failed!"<<endl;
}
};
//each step to create a checkBoard with weight
//w_O2 means two O already in a line, so Competitor have to attack, hold max weight for Competitor
//w_X2 means two X already in a line. so Competitor must defence, hold second largest weight for Competitor
//w_X1 means only one X in the line
//w_O1 means only one O in the line
//w_Empty means it is empty in the line
class InterMediateAI: public Competitor{
public:
//init weights
InterMediateAI():Competitor(O,"IntermediateAI"),w_O2(10000),w_X2(1000),w_x(10),w_o(6),w_Empty(4){
}
void desiredMove(vector<vector<Checker >> &checkBoard, Checker type) override{
checkerType = type;
vector<int> temp(3,0);
vector<vector<int>> levelBoard(3,temp);
//count different situation
for(int i = 0; i < checkBoard.size();i++){
for(int j = 0; j < checkBoard[i].size();j++){
//count weight in empty place
if(checkBoard[i][j] == EMPTY){
//count weights of same row
int res = countWeight(checkBoard[i][0],checkBoard[i][1], checkBoard[i][2]);
if(res != -1){
levelBoard[i][j] = levelBoard[i][j] + res;
}
//count weights of same column
res = countWeight(checkBoard[0][j],checkBoard[1][j],checkBoard[2][j]);
if(res != -1){
levelBoard[i][j] = levelBoard[i][j] + res;
}
//in the mainDiagonal
if((i == 0 && j == 0) || (i == 1 && j == 1) || (i == 2 && j == 2)){
res = countWeight(checkBoard[0][0]