猫でもわかるWeb開発・プログラミング

本業エンジニアリングマネージャー。副業Webエンジニア。Web開発のヒントや、副業、日常生活のことを書きます。

AOJ 2311: Dessert Witch (お菓子の魔女)

はじめに

方針

  • 元ネタは『魔法少女まどか☆マギカ
  • 頑張って実装するだけ
  • 巴マミのターンば上優先のなかで左優先、魔女のターンは下優先のなかで右優先なので注意(最初ここでハマった…)

ソースコード

  • 配列飛び出すかどうかの時に例外処理するの、何も考えなくていいから楽だけど、コードはぐちゃぐちゃになるからやらないほうがいい。
class Main extends MyUtil{
    // public static Graph g;
    public static void main(String[] args) throws Exception{
        // ボードの入力を受ける
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        char[][] table = new char[8][8];
        for(int i = 0; i < 8; i++){
            table[i] = br.readLine().toCharArray();
        }
        
        Board b = new Board(table);
        char[] marks = {'o', 'x'};
        int turn = 0;
        boolean prev_finish_flag = false;
        while(true){
            char m = marks[turn];
            boolean curr_finish_flag = false;
            if(b.turn(m) == 0) curr_finish_flag = true;
            if(prev_finish_flag && curr_finish_flag) break;
            
            turn = (turn + 1) % 2;
            prev_finish_flag = curr_finish_flag;
            // b.print();
            // System.out.println();
        }
        b.print();
    }
}

class Board{
    char[][] table;
    Board(char[][] table){
        this.table = table;
    }
    
    void print(){
        for(int i = 0; i < 8; i++){
            StringBuffer buf = new StringBuffer();
            for(int j = 0; j < 8; j++){
                buf.append(table[i][j]);
            }
            System.out.println(buf.toString());
        }
    }
    
    int turn(char m){
        int max_i = -1, max_j = -1;
        int max_cnt = 0;
        
        for(int i = 0; i < 8; i++){
            for(int j = 0; j < 8; j++){
                if(table[i][j] != '.') continue;
                int cnt = check(m, i, j, false);
                if(cnt > max_cnt && m == 'o' ||
                        cnt >= max_cnt && m == 'x'){
                    max_cnt = cnt;
                    max_i = i;
                    max_j = j;
                }
            }
        }

        // System.out.println("" + m + " " + max_cnt + " " + max_i + " " + max_j);
        if(max_cnt > 0){
            check(m, max_i, max_j, true);
        }
        return max_cnt;
    }
    
    static int[] di = {-1,-1,-1,0,0,1,1,1};
    static int[] dj = {-1,0,1,-1,1,-1,0,1};
    int check(char m, int i, int j, boolean replace_flag){
        int sum = 0;
        for(int k = 0; k < 8; k++){
            int cnt;
            for(cnt = 1; cnt <= 8; cnt++){
                try{
                    char table_mark = table[i + cnt*di[k]][j + cnt*dj[k]];
                    if(table_mark == m){
                        // 必要ならここで置き換える
                        if(replace_flag){
                            table[i][j] = m;
                            for(int mult = cnt-1; mult > 0; mult--){
                                try{
                                    table[i + mult*di[k]][j + mult*dj[k]] = m;
                                }catch(Exception e){
                                    continue;
                                }
                            }
                        }
                        break;
                    }else if(table_mark == '.'){
                        cnt = 1;
                        break;
                    }
                }catch(Exception e){
                    // マスを飛び出した場合
                    // System.err.println(e);
                    cnt = 1;
                    break;
                }
            }
            sum += (cnt - 1);
        }
        return sum;
    }
}