Uva220 Othello

这道题所描述的棋就是有些人所称的“黑白棋”

可以按照题目的意思“模拟”这道题,“黑白棋”除了水平及树直方向外,还需考虑斜线方向。

题目要求的格式中,如样例“Black -  1 White -  4”,数字1和4在输出时应用“ %2d”输出,而不是在数字前加两个空格。

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

const int MAXN = 8;
char chess[ MAXN+5 ][ MAXN+5 ];
char opColor; // 现在要摆的棋子的颜色
char oppoColor[300]; // 相反的颜色

int CountColor( char color ) { // 数某个颜色的棋子的数量
    int sum = 0;
    int i, j;
    for( i=1; i<=MAXN; i++ ) {
        for( j=1; j<=MAXN; j++ ) {
            sum = sum + (chess[i][j] == color) ;
        }
    }
    return sum;
}

bool CanPlaced( int x, int y, int dirx, int diry ) { // // 从从某个方向开始,dirx, diry的值用于控制方向
    int i, j;
    bool findOppoColor = false;
    for( i=x+dirx, j=y+diry; i>=1 && i<=MAXN && j>=1 && j<=MAXN ; i+=dirx, j+=diry ) {
        if( chess[i][j] == ‘-‘ ) {
            return false;
        } else if( chess[i][j] == oppoColor[ opColor ] ) {
            findOppoColor = true;
        } else if( chess[i][j] == opColor ) {
            if( findOppoColor ) {
                return true;
            } else {
                return false;
            }
        }
    }
    return false;

}

bool CanPlaced( int x, int y ) { // eight directions
    return CanPlaced( x, y, -1,0 ) || CanPlaced( x, y, 1,0 ) || CanPlaced( x, y, 0, 1 ) || CanPlaced( x, y, 0, -1 ) || CanPlaced( x, y, 1, 1 ) || CanPlaced( x, y, -1, 1 ) || CanPlaced( x, y, 1, -1 ) || CanPlaced( x, y, -1, -1 ); // 有一个方向能放就行
}

void List() { // 列出所有能摆放棋子的位置
    int i, j;
    bool first = true;
    for( i=1; i<=MAXN; i++ ) {
        for( j=1; j<=MAXN; j++ ) {
            if( chess[i][j]==‘-‘ && CanPlaced( i, j ) ) {
                if( first ) {
                    first = false;
                    printf( "(%d,%d)", i, j );
                }else {
                    printf( " (%d,%d)", i, j );
                }
            }
        }
    }
    if( first == true ) {
        printf( "No legal move.\n" );
    } else {
        printf( "\n" );
    }
}

bool Change( int x, int y, int dirx, int diry ) { // 从从某个方向开始,dirx, diry的值用于控制方向
    int i, j;
    bool flag = false;
    for( i=x+dirx, j=y+diry; i>=1 && i<=MAXN && j>=1 && j<=MAXN ; i+=dirx, j+=diry ) {
        if( chess[i][j] == ‘-‘ ) {
            return false;
        } else if( chess[i][j] == opColor ) {
            flag = true;
            break;
        }
    }
    if( flag == false ) { // no find opColor
        return false;
    }
    flag = false;
    for( i=x+dirx, j=y+diry; i>=1 && i<=MAXN && j>=1 && j<=MAXN ; i+=dirx, j+=diry ) {
        if( chess[i][j] == oppoColor[ opColor ] ) {
            chess[i][j] = opColor;
            flag = true;
        } else if( chess[i][j] == opColor ) {
            break;
        }
    }
    return flag;
}

bool Move( int x, int y ) {
    chess[ x ][ y ] = opColor;
    Change( x, y, -1,0 );
    Change( x, y, 1,0 );
    Change( x, y, 0, 1 );
    Change( x, y, 0, -1 );
    Change( x, y, 1, 1 );
    Change( x, y, -1, 1 );
    Change( x, y, 1, -1 );
    Change( x, y, -1, -1 ); // 从各个方向试图进行更改
    /*
       Change( x, y, -1,0 ) || Change( x, y, 1,0 ) ||
       Change( x, y, 0, 1 ) || Change( x, y, 0, -1 ) || Change( x, y, 1, 1 )
       || Change( x, y, -1, 1 ) || Change( x, y, 1, -1 ) || Change( x, y, -1, -1 );
       原先这样写的,但改成上面这样子就对了
       原因是:如果用"或",那么如果第一个方向对了,后面几个函数就不会执行,而后面几个函数可能有几个是符合题意可以翻棋子的,所以
       改用"或"是很糟糕的做法
    */
    printf( "Black -%3d White -%3d\n", CountColor( ‘B‘ ), CountColor( ‘W‘ ) );
    return true;
}

void PrintChess() { // 打印棋盘
    int i;
    for( i=1; i<=MAXN; i++ ) {
        printf( "%s\n", chess[i]+1 );
    }
}

int main() {
    int T;
    cin >> T;
    int i, j;
    oppoColor[ ‘B‘ ] = ‘W‘;
    oppoColor[ ‘W‘ ] = ‘B‘;
    while( T-- ) {
        for( i=1; i<=MAXN; i++ ) {
            scanf( "%s", chess[i]+1 );
        }
        char s[5];
        cin >> opColor;
        while( true ) {
            cin >> s;
            if( s[0] == ‘L‘ ) {
                List(); // 列出所有能摆放棋子的位置
            } else if( s[0] == ‘M‘ ) {
                if( CanPlaced( s[1]-‘0‘, s[2]-‘0‘ ) ) { // 这里能否放棋子
                    Move( s[1]-‘0‘, s[2]-‘0‘ );
                } else {
                    opColor = oppoColor[ opColor ]; // 如果不能,由另外一名选手摆放(题目中已阐明当前无法放时,另一名选手必定能放)
                    Move( s[1]-‘0‘, s[2]-‘0‘ );
                }
                opColor = oppoColor[ opColor ];
            } else if( s[0] == ‘Q‘ ) {
                PrintChess(); // 打印棋盘
                break;
            }
        }
        if( T ) {
            printf( "\n" );
        }
    }
    return 0;
}
时间: 2025-01-04 23:47:48

Uva220 Othello的相关文章

[LeetCode] 8.8 Othello Game 黑白棋游戏

8.8 Othello is played as follows: Each Othello piece is white on one side and black on the other. When a piece is surrounded by its opponents on both the left and right sides, or both the top and bottom, it is said to be captured and its color is fli

Othello UVA - 220

https://vjudge.net/problem/UVA-220 和之前的xiangqi差不多,都是棋盘类的,在二维数组里做各种情况的判断.也是锻炼自定而下的编程方法. 题目中说要实现三个功能: ①:确定所有可以走的位置坐标,并以坐标形式输出. ②:要可以进行落子并且对按规则进行被前后夹死的对手棋子反转. ③:退出时要可以输出棋盘. (要注意这三件事是可以以任意顺序做的,不要理解为M之前必须先L,我就是这样wa了好久orz) 做①时我用的是遍历棋盘,对于当前自己的棋子进行判断,若自己棋子周身

算法竞赛入门经典 第四章

[√ ] UVA1339 古老的密码 Ancient Cipher [√ ] UVA489 刽子手的游戏 Hangman Judge [√ ] UVA133 救济金发放 The Dole Queue [√ ] UVA213 信息解码 Message Decoding [√ ] UVA512 追踪电子表格中的单元格 Spreadsheet Tracking [√ ] UVA12412 师兄帮帮忙 A Typical Homework (a.k.a Shi Xiong Bang Bang Mang)

前端网站资源精编!!

不要吝啬你的赞美喜欢就点个赞 目录: 1-------- 走进前端2-------- jQuery3-------- CSS4-------- Angularjs5-------- ES66-------- React7-------- 移动端API8-------- avalon9-------- Requriejs10-------- vue11-------- Seajs12-------- Less,sass13-------- Markdown14-------- D315------

看着看着就哭了的前端地址大全

原文地址:http://www.w3cfuns.com/notes/16438/db8e9e0bf80676f32b2cafb9b4932313.html 综合类 | 地址--- | --- 前端知识体系|http://www.cnblogs.com/sb19871023/p/3894452.html前端知识结构|https://github.com/JacksonTian/fksWeb前端开发大系概览|https://github.com/unruledboy/WebFrontEndStack

Android v4包中的 SwipeRefreshLayout 官方的下拉刷新组件

SwipeRefreshLayout在v4包下,对应的v4Demo中也有相应的例子.如果没有请下载最新support-v4 SwipeRefreshLayout 只能有一个直接子View,可能是一个ListView或一个Layout或其他需要刷新的组件. setOnRefreshListener 用于监听刷新的动作.SwipeRefreshLayout 下拉,就会有刷新的效果出来,触发该监听. 如果需要一个刷新的动画,setRefreshing(true), 停: setRefreshing(f

fragment实例

fragment_layout.xml: <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="matc

紫书第4章 函数和递归

1  序 系统的整理下第四章的学习笔记.同上次一样,尽量在不依赖书本的情况下自己先把例题做出来.这次有许多道题代码量都比较大,在例题中我都用纯C语言编写,但由于习题的挑战性和复杂度,我最终还是决定在第五章开始前,就用C++来完成习题.不过所有的代码都是能在C++提交下AC的. 在习题中,我都习惯性的构造一个类来求解问题,从我个人角度讲,这会让我的思路清晰不少,希望自己的一些代码风格不会影响读者对解题思路的理解. 其实在第四章前,我就顾虑着是不是真的打算把题目全做了,这些题目代码量这么大,要耗费很

HDU 3368 Reversi

Reversi Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1364    Accepted Submission(s): 540 Problem Description Reversi, also called Othello, is a two-sided game.Each of the two sides correspond