精华内容
下载资源
问答
  • C# 黑白棋 代码

    2011-12-22 22:29:55
    可视化课程设计作业,编码简单,可读性好,有足够的代码注释,希望可以帮到大家
  • C语言编写的黑白棋游戏,注释详细,简单明了,可以参考一下
  • 拼图,黑白棋,俄罗斯方块游戏的源代码内部都有注释,资源为压缩文件
  • 本程序是在已有的《黑白棋》基础上实现的网络版,通过Winsocket实现了进程的同步,源程序有比 较详细的注释,适合于大家参考
  • 黑白棋VC实现源码

    2012-11-29 13:59:52
    黑白棋源码包括客户端和服务器端 实现人人对战模式 代码注释很全 适合vc游戏开发初学者研究学习
  • 06 黑白棋

    2015-08-28 16:12:02
    1. 前言这个是在贴吧 看见一个网友写了一个关于五子棋的界面, 然后我也模拟写了一个, 但是后来无趣的时候, 将他改成了黑白棋的规则, 但是没有加入判断胜负的逻辑, 只是一个存在基本规则的界面而已 这个实际上写了...

    1. 前言

    这个是在贴吧 看见一个网友写了一个关于五子棋的界面, 然后我也模拟写了一个, 但是后来无趣的时候, 将他改成了黑白棋的规则, 但是没有加入判断胜负的逻辑, 只是一个存在基本规则的界面而已
    这个实际上写了已经很久了,所以可能注释, 代码风格等信息可能不是那么的好看
    备注 : 没有AI

    设计思路 : 难点主要在于对于八个方向上的可吃的棋子的处理

    元素介绍
    棋盘 : 我们看到的是一个形象的视图, BlackAndWhite中存在一个逻辑上的棋盘
    棋子 : 用户下子双方控制的棋子

    游戏画面 :
    这里写图片描述

    2. 基本的数据结构介绍

    2.1 BlackAndWhite : 整个业务逻辑的核心Model, 控制着吃掉可吃掉的棋子[updatePieces ]

    /**
     * file name : BlankAndWhite.java
     * created at : 9:16:59 PM May 27, 2015
     * created by 970655147
     */
    
    package com.hx.blankAndWhite;
    
    
    public class BlankAndWhite {
    
        private int[][] pieces;     // 每个"下子"的逻辑数据
    
        // 初始化
        public BlankAndWhite() {
            pieces = new int[Tools.ROWLINESNUM][Tools.COLLINENUM];
        }
    
        // 判断(row, col)是否可落子
        public boolean isBlank(int row, int col) {
            return pieces[row][col] == Tools.BLANK;
        }
    
        // 设置某一个坐标的棋子
        public void setGrid(int row, int col, int val) {
            pieces[row][col] = val;
    
            updatePieces(row, col, val);
        }
    
        // 更新可更新的棋子
            // 依次更新 下方, 上方, 右方, 左方的棋子
            // 依次更新 右上方, 左上方, 右下方, 左下的棋子
        private void updatePieces(int row, int col, int val) {
            if(val != Tools.BLANK) {
                // -----------split-------------
                // TT -> TF -> FT -> FF
                boolean isRow = true, isInc = true;
                int tmp = moveToAnotherSamePiece(row, col, isRow, isInc, val);
                if(pieces[tmp][col] == val) {
                    setPieces(row, col, tmp, col, val);
                }
    
                isInc = !isInc;
                tmp = moveToAnotherSamePiece(row, col, isRow, isInc, val);
                if(pieces[tmp][col] == val) {
                    setPieces(row, col, tmp, col, val);
                }
    
                isRow = !isRow;
                isInc = !isInc;
                tmp = moveToAnotherSamePiece(row, col, isRow, isInc, val);
                if(pieces[row][tmp] == val) {
                    setPieces(row, col, row, tmp, val);
                }
    
                isInc = !isInc;
                tmp = moveToAnotherSamePiece(row, col, isRow, isInc, val);
                if(pieces[row][tmp] == val) {
                    setPieces(row, col, row, tmp, val);
                }
    
                // -----------split-------------
                // TT -> TF -> FT -> FF
                boolean isUp = true, isRight = true;
                int rowTmp = -1, colTmp = -1;
                tmp = moveToAnotherSamePieceSidely(row, col, isUp, isRight, val);
                rowTmp = getRow(row, isUp, tmp);
                colTmp = getCol(col, isRight, tmp);
                if(pieces[rowTmp][colTmp] == val) {
                    setPiecesSidely(row, col, isUp, isRight, tmp, val);
                }
    
                isRight = !isRight;
                tmp = moveToAnotherSamePieceSidely(row, col, isUp, isRight, val);
                rowTmp = getRow(row, isUp, tmp);
                colTmp = getCol(col, isRight, tmp);
                if(pieces[rowTmp][colTmp] == val) {
                    setPiecesSidely(row, col, isUp, isRight, tmp, val);
                }
    
                isUp = !isUp;
                isRight = !isRight;
                tmp = moveToAnotherSamePieceSidely(row, col, isUp, isRight, val);
                rowTmp = getRow(row, isUp, tmp);
                colTmp = getCol(col, isRight, tmp);
                if(pieces[rowTmp][colTmp] == val) {
                    setPiecesSidely(row, col, isUp, isRight, tmp, val);
                }
    
                isRight = !isRight;
                tmp = moveToAnotherSamePieceSidely(row, col, isUp, isRight, val);
                rowTmp = getRow(row, isUp, tmp);
                colTmp = getCol(col, isRight, tmp);
                if(pieces[rowTmp][colTmp] == val) {
                    setPiecesSidely(row, col, isUp, isRight, tmp, val);
                }
    
            }
        }
    
        // 移动到下一个非opposite的位置[水平, 垂直方向均可]
        // isRow 表示是否是垂直方向
        // isInc 表示是否递增
        private int moveToAnotherSamePiece(int row, int col, boolean isRow, boolean isInc, int val) {   
            int tmp = row + 1;
            if(!isRow ) {
                tmp = col + 1;
            }
            if(!isInc) {
                tmp -= 2;
            }
    
            if(isInc ) {
                if(isRow ) {
                    while(tmp < pieces.length && pieces[tmp][col] == getOppositeForPiece(val)) {
                        tmp ++;
                    }
                } else {
                    while(tmp < pieces[0].length && pieces[row][tmp] == getOppositeForPiece(val)) {
                        tmp ++;
                    }
                }
            } else {
                if(isRow ) {
                    while(tmp >= 0 && pieces[tmp][col] == getOppositeForPiece(val)) {
                        tmp --;
                    }
                } else {
                    while(tmp >= 0 && pieces[row][tmp] == getOppositeForPiece(val)) {
                        tmp --;
                    }
                }
            }
    
            return tmp;
        }
    
        // 返回斜着走的步数
        // isUp    表示是否是垂直方向
        // isRight 表示是否是水平方向
        private int moveToAnotherSamePieceSidely(int row, int col, boolean isUp, boolean isRight, int val) {    
            int tmp01 = row + 1;
            int tmp02 = col - 1;
            if(isUp ) {
                tmp01 -= 2;
            }
            if(isRight ) {
                tmp02 += 2;
            }
    
            if(isUp ) {
                if(isRight ) {
                    while(tmp01 >= 0 && tmp02 < pieces[0].length && pieces[tmp01][tmp02] == getOppositeForPiece(val)) {
                        tmp01 --;
                        tmp02 ++;
                    }
                } else {
                    while(tmp01 >= 0 && tmp02 >= 0 && pieces[tmp01][tmp02] == getOppositeForPiece(val)) {
                        tmp01 --;
                        tmp02 --;
                    }
                }
            } else {
                if(isRight ) {
                    while(tmp01 < pieces.length && tmp02 < pieces[0].length && pieces[tmp01][tmp02] == getOppositeForPiece(val)) {
                        tmp01 ++;
                        tmp02 ++;
                    }
                } else {
                    while(tmp01 < pieces.length && tmp02 >= 0 && pieces[tmp01][tmp02] == getOppositeForPiece(val)) {
                        tmp01 ++;
                        tmp02 --;
                    }
                }
            }
    
            return Math.abs(tmp01 - row);
        }
    
        // 设置(startRow, startCol) 到(endRow, endCol)区域的棋子为val
        private void setPieces(int startRow, int startCol, int endRow, int endCol, int val) {
            if(startRow > endRow) {
                int tmp = startRow;
                startRow = endRow;
                endRow = tmp;
            }
            if(startCol > endCol) {
                int tmp = startCol;
                startCol = endCol;
                endCol = tmp;
            }
    
            for(int i=startRow; i<=endRow; i++ ) {
                for(int j=startCol; j<=endCol; j++) {
                    pieces[i][j] = val;
                }
            }
        }
    
        // 从(startRow, startCol) 开始斜着设置cnt个坐标
        // isUp 表示是否向上移动
        // isRight 表示是否向右移动
        private void setPiecesSidely(int startRow, int startCol, boolean isUp, boolean isRight, int cnt, int val) {
            for(int i=0; i<cnt; i++) {
                pieces[startRow][startCol] = val;
                startRow = getNextRow(startRow, isUp);
                startCol = getNextCol(startCol, isRight);
            }
        }
    
        // 根据isUp 获取row的下一个行坐标
        private int getNextRow(int row, boolean isUp) {
            return getRow(row, isUp, 1);
        }
        //  根据isUp, offset 获取row的下一个行坐标
        private int getRow(int row, boolean isUp, int offset) {
            if(isUp) {
                return row - offset;
            } else {
                return row + offset;
            }
        }
    
        // 根据isRight 获取col的下一个列坐标
        private int getNextCol(int col, boolean isRight) {
            return getCol(col, isRight, 1);
        }
        //  根据isRight, offset 获取col的列标
        private int getCol(int col, boolean isRight, int offset) {
            if(isRight) {
                return col + offset;
            } else {
                return col - offset;
            }
        }
    
        // 获取val对立的棋子  如果是白棋 返回黑棋, 如果是黑棋 返回白棋
        private static int getOppositeForPiece(int val) {
            return Tools.WHITE_BLANK_SUM - val;
        }
    
        // 获取pieces
        public int[][] getPieces() {
            return pieces;
        }
    
        // 判断(row, col)是否是白棋
        public boolean isWhite(int row, int col) {
            return pieces[row][col] == Tools.WHITEPIECE;
        }
    }
    

    2.2 Tools : 存在一些常量 以及一些公共方法, 主要的方法是给定一个点, 找出其距离最近的棋盘上的点[比如 : 用户可能点击的并不在准确的棋子应该落子的位置, 这时候, 应该找出该点周围四个落子点中最近的落子点落子]

    package com.hx.blankAndWhite;
    
    public class Tools {
        // frame的宽高
        public static final int FRAMEWIDTH = 810;
        public static final int FRAMEHEIGHT = 600;
    
        // 一个格子的宽高
        public static final int GRIDWIDTH = 30;
        public static final int GRIDHEIGHT = 30;
    
        // 多少条行落子点/列落子点
        public static final int ROWLINESNUM = Tools.FRAMEHEIGHT / Tools.GRIDHEIGHT;
        public static final int COLLINENUM = Tools.FRAMEWIDTH / Tools.GRIDWIDTH;
    
        // 棋子的半径/一半半径
        public static final int PIECERADIS = 20;
        public static final int HALFPIECERADIS = PIECERADIS / 2;
    
        // frame的背景颜色 棋盘上线的颜色 白子的颜色 黑子的颜色
        public static final Color BGCOLOR = new Color(240, 225, 181);
        public static final Color LINECOLOR = new Color(52, 158, 213);
        public static final Color WHITECOLOR = new Color(255, 255, 255);
        public static final Color BLACKCOLOR = new Color(0, 0, 0);
    
        // 空白/黑子/白子 落子点的数据
        public static final int BLANK = 0;
        public static final int WHITEPIECE = 1;
        public static final int BLACKPIECE = 2;
        public static final int WHITE_BLANK_SUM = WHITEPIECE + BLACKPIECE;
    
        // 获取到离点p 最近的在交叉点上的点
        public static Point getLeastPoint(Point p) {
            // 找到离p的两对x y边缘坐标
            int pXLeft = p.x - p.x % Tools.GRIDWIDTH;
            int pYUp = p.y - p.y % Tools.GRIDHEIGHT;
            int pXRight = pXLeft + Tools.GRIDWIDTH;
            int pYDown = pYUp + Tools.GRIDHEIGHT;
    
            // 找到离p 最近的落子点
            double min = 0;
            Point res = p, p02 = null;
            p02 = new Point(pXLeft, pYUp);
    //      p.printInfo();  p02.printInfo();    Tools.printHorizon();
            double leftUp = getSquareDistance(p, p02);
            if(min < leftUp) {
                min = leftUp;   res = p02;
            }
            p02 = new Point(pXLeft, pYDown);
            double leftDown = getSquareDistance(p, p02);
            if(leftDown < min) {
                min = leftDown; res = p02;
            }
            p02 = new Point(pXRight, pYUp);
            double rightUp = getSquareDistance(p, p02);
            if(rightUp < min) {
                min = rightUp;  res = p02;
            }
            p02 = new Point(pXRight, pYDown);
            double rightDown = getSquareDistance(p, p02);
            if(rightDown < min) {
                min = rightDown;    res = p02;
            }
    
            return res;
        }
    
        // 调试
        public static void printHorizon() {
            System.out.println("----------------");
        }
    
        // 两个点的距离平方和
        public static double getSquareDistance(Point p1, Point p2) {
            return Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2);
        }
    
        // for debug ...
        public static void awaitInput() {
            try {
                System.in.read();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    }
    

    3 下载链接 [包含图片, 源码] :

    http://download.csdn.net/detail/u011039332/9058493
    这里写图片描述

    运行时截图 :

    这里写图片描述

    注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!

    展开全文
  • 黑白棋 AI(16*16)

    2018-04-19 18:22:29
    黑白棋,又叫翻转棋(Reversi)、奥赛罗棋(Othello)、苹果棋或反棋(Anti reversi),在西方和日本很流行。游戏通过相互翻转对方的棋子,最后以棋盘上谁的棋子多来...所有使用说明及算法简析均以注释形式附在代码中。
  • 1.[代码][C/C++]代码/** reversi.cpp* 转载请保留这段注释,注明原作者,以及出处,请尊重作者的劳动,谢谢!* Created on: 2012-11-27* Author: locusxt* blog: http://my.oschina.net/u/1053833*/#include#...

    1.[代码][C/C++]代码

    /*

    * reversi.cpp

    * 转载请保留这段注释,注明原作者,以及出处,请尊重作者的劳动,谢谢!

    * Created on: 2012-11-27

    * Author: locusxt

    * blog: http://my.oschina.net/u/1053833

    */

    #include

    #include

    #include

    #include

    #include

    using namespace std;

    int t[8] = {0};

    int huihe = 0;

    int g = 0, h = 0;

    int difficulty = 0;

    int dx[8] = {0, 1, 1, 1, 0, -1, -1, -1};

    int dy[8] = {-1, -1, 0, 1, 1, 1, 0, -1};

    int player, ai;

    int mover;

    int boardcopy[13][13];

    int board[13][13] = {0};

    //以下为优先权数组

    int priority[13][13] = {{0, 0, 0, 0, 0, 0, 0, 0, 0},

    {0, 10000, 1, 18, 14, 14, 18, 1, 10000},

    {0, 1, 1, 6, 7, 7, 6, 1, 1},

    {0, 18, 6, 18, 12, 12, 18, 6, 18},

    {0, 14, 13, 12, 11, 11, 12, 13, 14},

    {0, 14, 13, 12, 11, 11, 12, 13, 14},

    {0, 18, 6, 18, 12, 12, 18, 6, 18},

    {0, 1, 1, 6, 7, 7, 6, 1, 1},

    {0, 10000, 1, 18, 14, 14, 18, 1, 10000},

    };

    void save();//保存

    void load();//载入

    void printmap();//打印棋盘

    int direction (int x, int y, int dir, char turn, int mode[][13]);//判断个方向能吃的棋子个数

    int sum(int x, int y, int turn, int mode[][13]);//计数,放在(x,y)点可吃棋子总数

    void choose();//选择先下还是后下,先下输入1,后下输入2,并且告知棋子颜色

    int judgepass(int turn, int mode[][13] );//判断是否无棋可下,0代表不要pass,1则pass

    void reverse(int x, int y, int turn,int mode[][13]);//翻转已经被吃掉的棋子

    void input(int x, int y, int turn);//输入坐标或者指令

    void tryin(int turn);//电脑ai模拟下棋

    int calculate();//计算ai与player得分之差

    void test (int step);//ai模拟下棋函数

    float prio(int x, int y);//优先级函数

    void aiinput();//ai输入

    void mark(int turn);//标记可以下的位置

    void remark( );//取消标记

    void start();//游戏开始函数

    void result();//输出游戏结果

    void choosedifficulty();//选择难度

    void tempsave();//临时保存

    void choosemode();//选择模式

    void regret();//悔棋

    void outputhelp();//输出帮助文档

    void giveup();//认输

    int main ()

    {

    cout << "*******************************************" << endl;

    cout << " 黑白棋 "<< endl;

    cout << " Author:locusxt " << endl;

    cout << " 2012.12" << endl << endl << endl;

    board[4][4] = 2;

    board[4][5] = 1;

    board[5][4] = 1;

    board[5][5] = 2;

    outputhelp();

    choosemode();

    cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;

    result();

    cout << "Happy" << endl;

    cout << " New" << endl;

    cout << " Year!!!" << endl;

    cout << "是否重新开始?(Y/N)" << endl;//一局游戏结束后询问是否继续玩

    char letter;

    cin >> letter;

    if(letter == 'y')

    {

    system("CLS");

    system("reversi.exe");

    }

    else exit(0);

    system("pause");

    }

    void save()//保存功能

    {

    ofstream outfile("save.dat", ios::out);

    if(!outfile)

    {

    cerr << "open error!" << endl;

    exit(1);

    }

    else cout << "保存成功" << endl;

    outfile << player << " " << ai << " " << difficulty << " " << huihe << endl;

    for(int i = 1; i <= 8; i++)

    for(int j = 1; j <= 8; j++)

    outfile << board[i][j] << " ";

    outfile.close();

    }

    void load()//读取功能

    {

    ifstream infile("save.dat", ios::in);

    if(!infile)

    {

    cerr << "open error!" << endl;

    exit(1);

    }

    else cout << "载入成功" << endl;

    infile >> player >> ai >> difficulty >> huihe;

    mover = player;

    for(int i = 1; i <= 8; i++)

    for(int j = 1; j <= 8; j++)

    infile >> board[i][j];

    infile.close();

    }

    void printmap()//打印棋盘

    {

    cout << " A B C D E F G H " << endl;

    cout << " ┌─┬─┬─┬─┬─┬─┬─┬─┐" << endl;

    for(int i = 1; i <= 8; i++)

    {

    cout << i << "│" ;

    for(int j = 1; j <= 8; j++)

    {

    if(board[i][j] == 0) cout << " ";

    if(board[i][j] == 1) cout << "●";

    if(board[i][j] == 2) cout << "○";

    if(board[i][j] == 3) cout << "×";

    cout << "│";

    }

    if ( i < 8)cout << endl << " ├─┼─┼─┼─┼─┼─┼─┼─┤" << endl;

    else cout << endl << " └─┴─┴─┴─┴─┴─┴─┴─┘"<

    }

    int nplayer = 0, nai = 0;//同时输出比分

    for(int i = 1; i<= 8; i++)

    for(int j = 1; j<=8; j++)

    {

    if(board[i][j] == player) nplayer++;

    if(board[i][j] == ai) nai++;

    }

    cout << "ai : player =" << nai << ":" << nplayer << endl;

    }

    int direction (int x, int y, int dir, int turn, int mode[][13])//判断个方向能吃的棋子个数

    {

    if ((mode[x + dx[dir]][y + dy[dir]] == 0) || (mode[x + dx[dir]][y + dy[dir]] == 3)) return 0;

    if (mode[x + dx[dir]][y + dy[dir]] == turn) return t[dir];

    if ((x + dx[dir] < 1) || (x + dx[dir] > 8) || (y + dy[dir] < 1) || (y + dy[dir] > 8)) return 0;

    t[dir]++;

    return direction(x + dx[dir], y + dy[dir], dir, turn, mode);

    }

    int sum(int x, int y, int turn,int mode[][13])//计数,放在(x,y)点可吃棋子总数

    {

    int tep = 0;

    for(int i = 0; i <= 7; i++)

    {

    t[i] = 0;

    tep += direction(x, y, i, turn, mode);

    }

    return tep;

    }

    void choose()//选择先下还是后下,先下输入1,后下输入2,并且告知棋子颜色

    {

    char choice;

    cout << "请输入你的下棋次序(先下输入1,后下输入2)" << endl;

    cin >> choice;

    if(choice == '1')

    {

    player = 1;

    ai = 2;

    huihe = 1;

    cout << "你的棋子:●" << endl;

    }

    else if(choice == '2')

    {

    player = 2;

    ai = 1;

    huihe = 1;

    cout << "你的棋子:○" << endl;

    }

    else

    {

    cout << "无效的输入,请重新输入" << endl;

    choose();

    }

    cout << "按任意键继续....." << endl;

    getch();

    system("CLS");

    }

    int judgepass(int turn, int mode[][13])//判断是否无棋可下,0代表不要pass,1则pass

    {

    int tep = 0;

    for (int i = 1; i <= 8; i++)

    {

    for (int j = 1; j <= 8; j++)

    {

    if ((mode[i][j] == 0) && sum(i, j, turn, mode) != 0)

    {

    tep = 1;

    break;

    }

    }

    if(tep) break;

    }

    if(tep) return 0;

    return 1;

    }

    void reverse(int x, int y, int turn, int mode[][13])//翻转已经被吃掉的棋子

    {

    for(int l = 0; l <= 7; l++)

    {

    if(direction(x, y, l, turn, mode) != 0)

    for (int i = x + dx[l], j = y + dy[l]; ; i += dx[l], j += dy[l])

    {

    if (mode[i][j] != turn) mode[i][j] = turn;

    else break;

    }

    }

    }

    void input(int x, int y, int turn)//输入坐标或者指令

    {

    if(player == 1) cout << endl << "●";

    else cout << endl << "○";

    cout << "请输入坐标(先输数字再输字母.例:5c)或指令" <

    string order;

    cin >> order;

    if(order[0] == 's' || order[0] == 'l' || order[0] == 'm' || order[0] == 'r' || order[0] == 'e' || order[0] == 'h'|| order[0] == 'a'|| order[0] == 'g' || order[0] == 'c')

    {

    switch (order[0])

    {

    case 's'://s代表save保存

    system("CLS");

    save();

    break;

    case 'l'://l代表load读取

    system("CLS");

    load();

    break;

    case 'm'://m代表printmap打印棋盘

    mark(player);

    printmap();

    remark();

    break;

    case 'r'://r代表regret悔棋

    system("CLS");

    regret();

    break;

    case 'e'://e代表exit退出

    exit(0);

    break;

    case 'h'://h代表help输出帮助文档

    system("CLS");

    outputhelp();

    //printmap();

    break;

    case 'a'://a代表again重新开始

    system("CLS");

    system("reversi.exe");

    break;

    case 'c':

    system("CLS");

    break;

    case 'g'://g代表giveup认输

    cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;

    cout << "你认输了!!! ?_?" << endl << endl;

    cout << "是否重新开始?(Y/N)" << endl;

    char letter;

    cin >> letter;

    if(letter == 'y')

    {

    system("CLS");

    system("reversi.exe");

    }

    else exit(0);

    break;

    }

    start();

    }

    else//输入坐标,先数字后字母

    {

    x = order[0] - '0';

    y = order[1] - 'a' + 1;

    if((x >= 1) && (x <= 8) && (y >= 1) && (y <= 8) && ((board[x][y] == 0)||(board[x][y] == 3)) && (sum(x, y, turn, board) != 0))

    {

    tempsave();

    board[x][y] = turn;

    reverse(x, y, turn, board);

    }

    else

    {

    cout << "无效输入,请重新输入" << endl;

    input (x, y , turn);

    }

    }

    }

    void tryin(int turn)//电脑ai模拟下棋

    {

    int max = -1000000, xx = 0, yy = 0;

    for(int i = 1; i <= 8; i++)

    for(int j = 1; j <= 8; j++)

    {

    if(max < sum(i, j, turn, boardcopy) + priority[i][j] && ((boardcopy[i][j] == 0) || (boardcopy[i][j] == 3)))

    {

    max = sum(i, j, turn, boardcopy) + priority[i][j] ;

    xx = i;

    yy = j;

    }

    }

    boardcopy[xx][yy] = turn;

    reverse(xx, yy, turn, boardcopy);

    }

    int calculate()//计算ai与player得分之差

    {

    int nplayer = 0, nai = 0;

    for(int i = 1; i<= 8; i++)

    for(int j = 1; j<=8; j++)

    {

    if(boardcopy[i][j] == player) nplayer += priority[i][j] ;

    if(boardcopy[i][j] == ai) nai += priority[i][j] ;

    }

    return nai - nplayer;

    }

    void test (int step)//ai模拟下棋函数

    {

    if(step == 1)

    {

    if(!(judgepass(player,boardcopy))) tryin(player);

    step ++;

    test(step);

    return;

    }

    if((step > 1)&&(step <= difficulty + 10))

    {

    if(!(judgepass(ai,boardcopy))) tryin(ai);

    if(!(judgepass(player,boardcopy))) tryin(player);

    step ++;

    test(step);

    return;

    }

    return;

    }

    float prio(int x, int y)//优先级函数

    {

    for(int i = 1; i <= 8; i++)

    for(int j = 1; j<= 8; j++)

    boardcopy[i][j] = board[i][j];

    int tep = calculate();

    if(sum(x,y,ai,boardcopy) != 0)

    {

    boardcopy[x][y] = ai;

    test(1);

    return calculate() - tep + priority[x][y];

    }

    else return 0;

    }

    void aiinput()//ai输入函数

    {

    int max = -1000000;

    g = 0;

    h = 0;

    for(int i = 1; i <= 8; i++)

    for(int j = 1; j <= 8; j++)

    {

    if(max < prio(i,j)&&((board[i][j] == 0)||(board[i][j] == 3))&&(sum(i,j,ai,board) != 0))

    {

    max = prio(i,j);

    g = i;

    h = j;

    }

    }

    board[g][h] = ai;

    reverse(g,h,ai, board);

    cout<< "***********************************************" << endl;

    cout << endl << "ai将要输入的是" << g ;//ai输入前暂停,让玩家知道ai下棋的位置

    putchar(h + 'a' - 1);

    cout << endl;

    cout << "按任意键继续......" << endl;

    getch();

    }

    void mark(int turn)//标记可以下的位置

    {

    for(int i = 1; i <= 8; i++)

    for(int j = 1; j <= 8; j++)

    if((board[i][j] == 0)&&(sum(i,j,turn, board) != 0)) board[i][j] = 3;

    }

    void remark()//取消棋盘标记

    {

    for(int i = 1; i <= 8; i++)

    for(int j = 1; j <= 8; j++)

    if(board[i][j] == 3) board[i][j] = 0;

    }

    void start ()//游戏开始函数

    {

    while (true)

    {

    if((judgepass(ai, board)) && (judgepass(player, board)))//判断游戏是否已经结束

    {

    printmap();

    break;

    }

    if(mover == player)

    {

    if(judgepass(player, board))//判断是否是pass

    {

    huihe++;

    cout << " 回合:" << huihe / 2 << " 难度:" << difficulty << endl;

    printmap();

    cout<

    cout << "player pass ~~>_

    mover = ai;

    cout << "按任意键继续......" << endl;

    getch();

    system("CLS");

    }

    else

    {

    huihe++;

    cout << " 回合:" << huihe / 2 << " 难度:" << difficulty << endl;

    mark(mover);

    printmap();

    cout<

    remark();

    int p, q;

    input(p, q, mover);

    mover = ai;

    system("CLS");

    }

    }

    else

    {

    if(judgepass(ai, board))//判断是否是pass

    {

    huihe++;

    cout << " 回合:" << huihe / 2 << " 难度:" << difficulty << endl;

    printmap();

    cout<

    cout << "ai pass 0^_^0" << endl;

    mover = player;

    cout << "按任意键继续......" << endl;

    getch();

    system("CLS");

    }

    else

    {

    huihe++;

    cout << " 回合:" << huihe / 2 << " 难度:" << difficulty << endl;

    printmap();

    aiinput();

    mover = player;

    system("CLS");

    }

    }

    }

    }

    void result()//结果函数,用于输出结果

    {

    tempsave();

    int nplayer = 0, nai = 0;

    for(int i = 1; i<= 8; i++)

    for(int j = 1; j<=8; j++)

    {

    if(board[i][j] == player) nplayer++;

    if(board[i][j] == ai) nai++;

    }

    cout << "ai : player =" << nai << ":" << nplayer << endl;

    if(nai > nplayer) cout <

    if(nai < nplayer) cout <

    if(nai == nplayer) cout << "平局... @_@" << endl;

    }

    void choosedifficulty()//选择难度

    {

    cout << "输入你选择的难度(1~6)" << endl;

    cin >> difficulty;

    if((difficulty > 6)||(difficulty < 1))

    {

    cout << "无效输入,请重新输入" << endl;

    choosedifficulty();

    }

    }

    void choosemode()//选择模式

    {

    char mode_choose;

    cout << "****************模式选择******************" << endl << endl;

    cout << "请选择模式....(输入1或2或3)" << endl << endl;

    cout << " 1.新游戏" << endl << endl;

    cout << " 2.载入存档" << endl << endl;

    cout << " 3.继续上次游戏" << endl;

    cin >> mode_choose;

    while (true)

    {if(!(mode_choose == '1'|| mode_choose == '2'|| mode_choose == '3'))

    {

    cout << "无效输入,请重新选择..." << endl;

    cin >> mode_choose;

    }else break;}

    switch (mode_choose)

    {

    case '1':

    choosedifficulty();

    mover = 1;

    choose();

    start();

    break;

    case '2':

    system("CLS");

    load();

    start();

    break;

    case '3':

    regret();

    start();

    break;

    }

    }

    void tempsave()//临时存档,用于实现悔棋以及继续上次游戏的功能

    {

    ofstream outfile("tempsave.dat", ios::out);

    if(!outfile)

    {

    cerr << "open error!" << endl;

    exit(1);

    }

    outfile << player << " " << ai << " " << difficulty << " " << huihe << endl;

    for(int i = 1; i <= 8; i++)

    for(int j = 1; j <= 8; j++)

    outfile << board[i][j] << " ";

    outfile.close();

    }

    void regret()//悔棋函数,读取上一步的临时存档

    {

    ifstream infile("tempsave.dat", ios::in);

    if(!infile)

    {

    cerr << "open error!" << endl;

    exit(1);

    }

    else cout << "载入成功" << endl;

    infile >> player >> ai >> difficulty >> huihe;

    mover = player;

    for(int i = 1; i <= 8; i++)

    for(int j = 1; j <= 8; j++)

    infile >> board[i][j];

    infile.close();

    }

    void outputhelp()//输出帮助文档

    {

    cout << "********************帮助*******************" << endl << endl;

    cout << "指令一览:(输入指令时只需输入对应字母后回车)" <

    cout << " s --> 存盘 | l --> 读盘" << endl;

    cout << " r --> 悔棋 | e --> 退出" << endl;

    cout << " g --> 认输 | a --> 重来" << endl;

    cout << " h --> 帮助 | c --> 清屏" << endl << endl;

    cout << "说明: " << endl;

    cout << " ×代表你可以下的位置" << endl;

    cout << " 本游戏仅允许一次悔棋" << endl;

    cout << " 所有输入的字母(指令或坐标)均为小写" << endl ;

    cout << " 请勿更改exe文件名(reversi)" << endl;

    cout << " 请勿随意删除两个dat文件" << endl << endl;

    cout << "按任意键继续......" << endl;

    getch();

    system("CLS");

    }

    展开全文
  • 1、C语言,平台VS2010(Visual_Studio_Pro_2010), 2、做到跟附件这个游戏80%相似就可以,游戏界面和控件可以一摸一样,但是代码...附件:reversi-master.rar是个黑白棋游戏,链接https://pan.baidu.com/s/1hsiGd6k
  • 习题4-3 黑白棋 UVa220

    2015-03-23 22:58:56
    2.解题思路:本题是一道模拟题,要求模拟黑白棋的三种操作。对于这类题,肯定是分情况编写相应的函数处理。不过本题的难点在于如何方便地寻找到合法位置。思考了一会儿,可以枚举每一个空位置,同时利用一个向量数组...

    1.题目描述:点击打开链接

    2.解题思路:本题是一道模拟题,要求模拟黑白棋的三种操作。对于这类题,肯定是分情况编写相应的函数处理。不过本题的难点在于如何方便地寻找到合法位置。思考了一会儿,可以枚举每一个空位置,同时利用一个向量数组方便来后续讨论,由于实现的细节较多,详细过程见代码注释。本题还有一个细节:在执行M命令时记得要更换当前的游戏者,题目中说了是两个人轮流下棋。

    3.代码:

    #define _CRT_SECURE_NO_WARNINGS 
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<sstream>
    #include<set>
    #include<vector>
    #include<stack>
    #include<map>
    #include<queue>
    #include<deque>
    #include<cstdlib>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    #include<functional>
    using namespace std;
    
    typedef pair<int, int> P;
    #define N 8
    char g[N][N];
    vector<P>pos;
    char player;//当前玩家,设为全局变量,便于后续讨论
    int dx[] = { -1, 1, 0, 0, -1, 1, -1, 1 };//利用向量数组,方便处理各种情况
    int dy[] = { 0, 0, -1, 1, -1, 1, 1, -1 };
    bool inside(int x, int y)
    {
    	if (x<0 || x>7 || y<0 || y>7)return false;
    	return true;
    }
    bool find(int d,int x,int y, char c)//沿着路径dx[d],dy[d]寻找目标棋子
    {
    	int w = dx[d], v = dy[d], i = x, j = y;
    	while (inside(i, j) && g[i][j] == 'W' + 'B' - c){ i += w; j += v; }
    	if (inside(i, j) && g[i][j] == c)return true; 
    	return false;
    }
    bool is_valid(char c, int x, int y)//判断该位置是否为合法放置位置
    {
    	if (c == 'W')
    	{
    		for (int d = 0; d < 8; d++)
    		if (inside(x + dx[d], y + dy[d]) && g[x + dx[d]][y + dy[d]]=='B')
    		{
    			int i = x + dx[d], j = y + dy[d];
    			if (find(d, i, j, 'W'))return true;
    		}
    		return false;
    	}
    	else
    	{
    		for (int d = 0; d < 8; d++)
    		if (inside(x + dx[d], y + dy[d]) && g[x + dx[d]][y + dy[d]] == 'W')
    		{
    			int i = x + dx[d], j = y + dy[d];
    			if (find(d, i, j, 'B'))return true;
    		}
    		return false;
    	}
    }
    bool find_pos()//寻找合法放置位置
    {
    	pos.clear();
    	for (int i = 0; i < 8; i++)
    	for (int j = 0; j < 8; j++)
    	if (g[i][j] == '-'&&is_valid(player, i, j))//枚举每一个位置
    		pos.push_back(P(i + 1, j + 1));
    	int len = pos.size();
    	if (len>0)return true;
    	else return false;
    }
    void place(int x, int y)//放置棋子
    {
    	if (player == 'W')
    	{
    		g[x][y] = 'W';
    		for (int d = 0; d < 8;d++)
    		if (inside(x + dx[d], y + dy[d]) && g[x + dx[d]][y + dy[d]] == 'B')
    		{
    			int i = x + dx[d], j = y + dy[d];
    			if (find(d, i, j, 'W'))
    			{
    				int w = dx[d], v = dy[d];
    				while (g[i][j] != 'W'){ g[i][j] = 'W'; i += w; j += v; }
    			}
    		}
    	}
    	else
    	{
    		g[x][y] = 'B';
    		for (int d = 0; d < 8; d++)
    		if (inside(x + dx[d], y + dy[d]) && g[x + dx[d]][y + dy[d]] == 'W')
    		{
    			int i = x + dx[d], j = y + dy[d];
    			if (find(d, i, j, 'B'))
    			{
    				int w = dx[d], v = dy[d];
    				while (g[i][j] != 'B'){ g[i][j] = 'B'; i += w; j += v; }
    			}
    		}
    	}
    }
    void print_num()//打印黑白棋的个数
    {
    	int n1, n2;
    	n1 = n2 = 0;
    	for (int i = 0; i < 8;i++)
    	for (int j = 0; j < 8;j++)
    	if (g[i][j] == 'W')n1++;
    	else if (g[i][j]=='B')n2++;
    	printf("Black - %2d White - %2d\n", n2, n1);
    }
    void print_board()//打印当前棋盘
    {
    	for (int i = 0; i < 8; i++)
    	for (int j = 0; j < 8; j++)
    		printf("%c%s", g[i][j], j == 7 ? "\n":"");
    }
    int main()
    {
    	//freopen("t.txt", "r", stdin);
    	int T;
    	cin >> T;
    	int rnd = 0;
    	while (T--)
    	{
    		memset(g, '\0', sizeof(g));
    		for (int i = 0; i < 8; i++)
    			scanf("%s", g[i]);
    		cin >> player;
    		char cmd;
    		if (rnd++)cout << endl;
    		while (cin >> cmd)
    		{
    			if (cmd == 'L')
    			{
    				if (find_pos())
    				{
    					int len = pos.size();
    					for (int i = 0; i < len; i++)
    						printf("(%d,%d)%c", pos[i].first, pos[i].second, i == len - 1 ? '\n' : ' ');
    				}
    				else puts("No legal move.");
    			}
    			if (cmd == 'M')
    			{
    				char str[10];
    				scanf("%s", str);
    				int r, c;
    				r = str[0] - '0' - 1, c = str[1] - '0' - 1;
    				if (g[r][c]=='-'&&!is_valid(player, r, c)){ player = 'W' + 'B' - player;  }
    				place(r, c);
    				print_num();
    				player = 'W' + 'B' - player;
    			}
    			if (cmd == 'Q')
    			{
    				print_board();
    				break;
    			}
    		}
    	}
    	return 0;
    }

    展开全文
  • 原创,直接在终端运行,首先make othello,然后./othello运行,输入每行每列想要下的位置回车即可。编写时的注释为法语,可以忽略,直接看代码。人机使用了Alpha-Beta算法。直接使用里面的语句时请注明出处。
  • 题意:黑白棋都翻转成白色。规则是当我翻转其中一个时,它周围的4个棋子跟着它一块翻转。目标是用最少的步数把他们都翻转成白色,1代表黑,0代表白色; 思路:可以利用第一层的 2^n 种状态来进行枚举。依次翻转到最后...

    http://poj.org/problem?id=3279
    Fliptile
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 9926   Accepted: 3692

    Description

    Farmer John knows that an intellectually satisfied cow is a happy cow who will give more milk. He has arranged a brainy activity for cows in which they manipulate an M × N grid (1 ≤ M ≤ 15; 1 ≤ N ≤ 15) of square tiles, each of which is colored black on one side and white on the other side.

    As one would guess, when a single white tile is flipped, it changes to black; when a single black tile is flipped, it changes to white. The cows are rewarded when they flip the tiles so that each tile has the white side face up. However, the cows have rather large hooves and when they try to flip a certain tile, they also flip all the adjacent tiles (tiles that share a full edge with the flipped tile). Since the flips are tiring, the cows want to minimize the number of flips they have to make.

    Help the cows determine the minimum number of flips required, and the locations to flip to achieve that minimum. If there are multiple ways to achieve the task with the minimum amount of flips, return the one with the least lexicographical ordering in the output when considered as a string. If the task is impossible, print one line with the word "IMPOSSIBLE".

    Input

    Line 1: Two space-separated integers: M and N 
    Lines 2..M+1: Line i+1 describes the colors (left to right) of row i of the grid with N space-separated integers which are 1 for black and 0 for white

    Output

    Lines 1..M: Each line contains N space-separated integers, each specifying how many times to flip that particular location.

    Sample Input

    4 4
    1 0 0 1
    0 1 1 0
    0 1 1 0
    1 0 0 1

    Sample Output

    0 0 0 0
    1 0 0 1
    1 0 0 1
    0 0 0 0
    题意:黑白棋都翻转成白色。规则是当我翻转其中一个时,它周围的4个棋子跟着它一块翻转。目标是用最少的步数把他们都翻转成白色,1代表黑,0代表白色;

    思路:可以利用第一层的 2^n 种状态来进行枚举。依次翻转到最后一行,如果最后一行均为白色,那么这种第一层状态可以达到效果。记录下来,最后取最少翻转次数的结果输出。具体实现细节和相关解释在代码注释中给出。

    (学到了利用二进制进行枚举的方便之处)

    具体看代码就能看懂。这道题一看我就觉得不会,看了博客分析了一会儿,才看懂啥意思。(估计自己过不了几天就会忘了,毕竟不是自己想出来的东西,虽然懂了代码,但是还是不知道为什么这样能求出答案0.0)

    AC代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<map>
    #include<string>
    #define LL long long
    #define eps 1e-8
    using namespace std;
    const int mod = 1e7+7;
    const int inf = 0x3f3f3f3f;
    const int maxx = 100100;
    const int N = 20;
    int ma[N][N],ans[N][N],a[N][N];
    int n,m,xx,yy,anss,flag;
    int dx[7]= {0,1,0,0,-1};
    int dy[7]= {0,0,1,-1,0};
    int fuc(int x,int y)//判断颜色
    {
        int tem=ma[x][y];
        for(int i=0; i<5; i++)
        {
            xx=x+dx[i];
            yy=y+dy[i];
            if(xx>=0&&xx<n&&yy>=0&&yy<m)
                tem+=a[xx][yy];
        }
        return tem&1;
    }
    int dfs()
    {
        for(int i=1; i<n; i++)
            for(int j=0; j<m; j++)
                if(fuc(i-1,j))//看上一个是否为黑色。
                    a[i][j]=1;//若为黑色则翻转。
        for(int i=0; i<m; i++)
            if(fuc(n-1,i))//看最后一行的的棋子是否有黑色的。
                return -1;
        int tmp=0;//若都为白色则统计翻转次数
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                tmp+=a[i][j];
        return tmp;
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            anss=inf,flag=0;
            for(int i=0; i<n; i++)
                for(int j=0; j<m; j++)
                    scanf("%d",&ma[i][j]);
            for(int i=0; i< 1<<m; i++)
            {
                memset(a,0,sizeof(a));
                for(int j=0; j<m; j++)
                    a[0][m-j-1]=i>>j&1;//转化为二进制存到a【0】【】中,注意顺序
                int num=dfs();
                if(num>=0&&anss>num)
                {
                    flag=1;
                    anss=num;
                    memcpy(ans,a,sizeof(a));//跟新答案
                }
            }
            if(!flag)
                printf("IMPOSSIBLE\n");
            else
            {
                for(int i=0;i<n;i++)
                {
                    for(int j=0;j<m;j++)
                    {
                        if(j)printf(" ");
                        printf("%d",ans[i][j]);
                    }printf("\n");
                }
            }
        }
        return 0;
    }










    展开全文
  • 一个JavaScript写的黑白棋AI

    万次阅读 2010-11-22 10:31:00
    首先,这个代码不是我写的,但注释是我加上去的。作者是shaofei cheng,他的网站:http://shaofei.name。第二,目前这个代码只是使用了 alpha-beta 剪枝,棋力还弱,有很大的优化空间。但是代码写得非常清晰,如果有...
  • 很早以前用turbo c 2.0...在ubuntu上的code::blocks上自己编译了allegro5,重新写了这个小游戏,代码很短,就不写注释了。放在这里做备忘吧。 /*allegro5+c2012/11/1ymc*/#include<stdio.h>#include<alleg...
  • 本程序可以实现人机对弈,是我发布的三种棋类(中国象棋,五子棋和黑白棋)之一。 实现了十种搜索引擎,包括常见的Alpha-Beta,历史启发,置换表,负极大值等。为了阅读方便,在次发布的是未经优化的代码,即使如此...
  • 本程序可以实现人机对弈,是我发布的三个棋类程序(象棋,五子棋和黑白棋)之一。 搜索引擎可以方便的升级。 几乎每一个函数都有注释,是了解人机对弈原理的好素材。 绝对超值!!
  • 本程序可以实现人机对弈,是我发布的三种棋类(中国象棋,五子棋和黑白棋)之一。 实现了十种搜索引擎,包括常见的Alpha-Beta,历史启发,置换表,负极大值等。为了阅读方便,在次发布的是未经优化的代码,即使如此...
  • 本文实例为大家分享了js实现双人五子棋小游戏的具体代码,供大家参考,具体内容如下 这是自己自学js的时候,在网上找的js...ps 我遇到的一些问题在代码中有注释 <!DOCTYPE html> <html> <head> <t
  • 创建黑白落子行为函数总结欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、...
  • 代码不写注释谁不想干你 题目我就不粘贴了 code #include <iostream> #include <cmath> using namespace std; int n, map[8][8], ans;//定义n为棋盘大小n*n矩阵,定义数组二维map来储存是否可以放...
  • Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰效果 Java绘制图片火焰效果,源代码相关注释:前景和背景Image对象、Applet和绘制火焰的效果的Image对象、Applet和绘制火焰的效果的Graphics对象、...

空空如也

空空如也

1 2 3
收藏数 47
精华内容 18
关键字:

黑白棋代码注释