zoukankan      html  css  js  c++  java
  • Othello UVA

    https://vjudge.net/problem/UVA-220

    和之前的xiangqi差不多,都是棋盘类的,在二维数组里做各种情况的判断。也是锻炼自定而下的编程方法。

    题目中说要实现三个功能:

    :确定所有可以走的位置坐标,并以坐标形式输出。

    :要可以进行落子并且对按规则进行被前后夹死的对手棋子反转。

    :退出时要可以输出棋盘。

    (要注意这三件事是可以以任意顺序做的,不要理解为M之前必须先L,我就是这样wa了好久orz)

    做①时我用的是遍历棋盘,对于当前自己的棋子进行判断,若自己棋子周身八个格子存在对手棋子,则在此方向进行进一步搜索,直到找到空坐标。(当然要判断一下出界)

    ③更简单,输出数组就好,每次输出一整个数组后要再多换一行(整个题目的最后一次不用)

    ②我做的时候不想再用遍历,所以就直接读取了①中存储的每个坐标,但是知道坐标是不够的,还要知道每个坐标吃子的方向才行,我只能想到用

    vector<pair<int,int>,pair<int,int>>这种容器来存储,两组一对数,一组存坐标,另一组存方位。

    最后因为是多组输入,所以一定要注意初始化!!!;

    #include<iostream>
    #include<string> 
    #include<vector>
    #include<algorithm>
    #include<map>
    #include<set>
    #define rep(i,n,t) for(int i=(n);i<(t);i++)
    #define per(i,n,t) for(int i=(n);i>(t);i--)
    #define mms(a,b) memset(a,b,sizeof(a))
    #define N 9
    using namespace std;
    
    int chessboard[N][N]; vector<pair<pair<int, int>, pair<int, int>>> Posi; int cntb = 0, cntw = 0;
    
    bool comp(pair<pair<int, int>, pair<int, int>> a, pair<pair<int, int>, pair<int, int>> b)//升序排列
    {
        if (a.first.first == b.first.first) return a.first.second < b.first.second;
        return a.first.first < b.first.first;
    }
    
    bool cheak(int x, int y)//检查坐标是否出界
    {
        return (x > 0 && y > 0 && x < N&&y < N);
    }
    
    void print_board()//打印整个棋盘
    {
        rep(i, 1, N)
        {
            rep(j, 1, N) {
                if (chessboard[i][j] == 0)cout << 'W';
                else if (chessboard[i][j] == 1)cout << 'B';
                else cout << '-';
            }
            cout << endl;
        }
    }
    
    bool search(int player)
    {
        rep(i, 1, N) rep(j, 1, N)//对于棋盘上每一个点
        {
            if (chessboard[i][j] == 1) cntb++; if (chessboard[i][j] == 0) cntw++;//数黑白子个数
            if (chessboard[i][j] == player)rep(x, -1, 2) rep(y, -1, 2)//搜索周身每格
            {
                if (x || y)
                {
                    int xx = i + x; int yy = j + y; int flag=0;
                    while (cheak(xx, yy) && (chessboard[xx][yy] == !player))//如果该坐标合法且上边的棋子为对手的。
                    {
                        xx+=x; yy+=y;//继续按该方向搜索
                        flag++;
                    }
                    if (flag>0) if (cheak(xx, yy)&&chessboard[xx][yy] == -1) Posi.push_back(make_pair(make_pair(xx, yy), make_pair(x, y)));//如果停止的原因是因为该坐标上无棋子,加入解答容器。
                }
            }
        }
        return Posi.size();//以Posi种有无答案作为返回值
    }
    
    
    void change(int player, int x, int y)
    {
        chessboard[x][y] = player; if (player) cntb++;else cntw++;
        rep(i, 0, Posi.size())
        {
            if (make_pair(x, y) == Posi[i].first)//先找路线,再找方向
            {
                int xx, yy, a, b;
                a = (-1)*Posi[i].second.first;
                b = (-1)*Posi[i].second.second;
                xx = x + a; yy = y + b;
                while (cheak(xx, yy)&&chessboard[xx][yy]!=player)
                {
                    chessboard[xx][yy] = player; 
                    if (player) { cntb++; cntw--; }
                    else { cntb--; cntw++; }
                    xx += a; yy += b;
                }
            }
        }
    }
    int main()
    {
        int n; cin >> n;
        rep(i, 0, n)//n次游戏
        {
            //初始化期盼和状态    
            mms(chessboard, -1); Posi.clear(); cntb = cntw = 0;
            rep(x, 1, N) rep(y, 1, N)
            {
                char chess; cin >> chess;
                if (chess == 'W') chessboard[x][y] = 0;
                else if (chess == 'B') chessboard[x][y] = 1;
            }
            int player = 1; char c; cin >> c;
            if (c == 'W') player = 0;
    
            //处理输入
            string S;
            while (cin >> S)
            {
                cntw = cntb = 0; Posi.clear();int have_posi = search(player); 
                if (S == "Q") { print_board(); if (i != n - 1) cout << endl; break; }
                else if (S == "L")
                {
                    if (have_posi)
                    {
                        sort(Posi.begin(), Posi.end(), comp);
                        set<pair<int, int>> Output;
                        vector<pair<pair<int, int>,pair<int,int>>>::iterator it = Posi.begin();
                        while (it != Posi.end()){Output.insert(it->first);it++;}
                        set<pair<int, int>>::iterator sit = Output.begin();
                        while (sit != Output.end())
                        {
                            if (sit != Output.begin()) cout << " (" << sit->first << "," << sit->second << ")";
                            else cout << "(" << sit->first << "," << sit->second << ")";
                            sit++;
                        }
                    }
                    else { cout << "No legal move."; player = !player; }//若无位置可走,转换玩家
                    cout << endl;
                }
                else
                {
                    change(player, S[1] - 48, S[2] - 48);
                    if (cntb < 10)cout << "Black -  "; else cout << "Black - ";
                    cout << cntb;
                    if (cntw < 10)    cout << " White -  "; else cout << " White - ";
                    cout << cntw << endl;
                    player = !player;//每次一名玩家走完,交换玩家并初始化Posi;
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    DevExpress ASP.NET Core Controls 2019发展蓝图(No.6)
    DevExpress v18.2版本亮点——Analytics Dashboard篇(二)
    VS插件CodeRush for Visual Studio发布v18.2.9|附下载
    DevExpress 2019 .NET产品现已完全支持Visual Studio 2019
    DevExpress v18.2版本亮点——Analytics Dashboard篇(一)
    Java开发神器——MyEclipse CI 2019.4.0 全新发布(附下载)
    DevExpress ASP.NET Core Controls 2019发展蓝图(No.5)
    JS原型链中的prototype与_proto_的个人理解与详细总结
    ASP.NET Core中的依赖注入(5):ServicePrvider实现揭秘【补充漏掉的细节】
    ASP.NET Core中的依赖注入(5): ServiceProvider实现揭秘 【解读ServiceCallSite 】
  • 原文地址:https://www.cnblogs.com/worldcreator-zh/p/10556040.html
Copyright © 2011-2022 走看看