码迷,mamicode.com
首页 > 其他好文 > 详细

Othello UVA - 220

时间:2019-03-19 01:04:01      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:memset   注意   target   编程   push   clu   存在   处理   个数   

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;
}

 

Othello UVA - 220

标签:memset   注意   target   编程   push   clu   存在   处理   个数   

原文地址:https://www.cnblogs.com/worldcreator-zh/p/10556040.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!