ことさら−古都プログラマーの更級日記

京都でお寺を回りながら御朱印集めをしていたエンジニアのブログ。おもに技術的なはなしとか日常的なはなし。たまにカメラの話や競馬の話も書きます。

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