井字棋游戏

游戏简介

三连棋游戏(两人轮流在印有九格方盘上划“+”或“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]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值