use std::io::{read_to_string, stdin}; const SIZE: usize = 16; const SIDE: usize = 4; fn tokenize(s: &Vec) -> u32 { let mut res: u32 = 0; for i in 0..SIDE { for j in 0..SIDE { let idx = (SIDE * (3 - i) + j); match s[i] { '.' => { res |= 0b10 << (2 * idx); // 2 BLANK } 'o' => { res |= 0b01 << (2 * idx); // 1 O } 'x' => { res |= 0b00 << (2 * idx); // 0 X } _ => { res |= 0b11 << (2 * idx); // 3 Err } } } } res } // x가 아무 수나 둘때 o가 어떤 수나 두더라도 x가 이길 수 있는 가능성이 무조건 있으면 forced_win // 자명한 forced_win의 예시 후보가 2개이상일때 fn get_el(tk: &u32, idx: u32) -> u32 { return (tk >> (2 * idx)) & 0b11; } fn add_el(tk: &u32, idx: u32, el: u32) -> u32 { let key = el << (2 * idx); return tk | key; } fn el_candiates(tk: &u32) -> Vec { let mut res = Vec::new(); for idx in 0..SIZE as u32 { if get_el(tk, idx) == 0b10 { res.push(idx); } } return res; } fn is_win(tk: &u32, turn: u32) -> bool { let mut res = 0; for idx in 0..SIZE as u32 { if get_el(tk, idx) == turn { res |= 1 << idx; } } // horz for y in 0..4 { if (res & (0b1111 << (4 * y))) == (0b1111 << (4 * y)) { return true; } } // vert for x in 0..4 { if (res & (0b0001000100010001 << x)) == (0b0001000100010001 << x) { return true; } } // diag if (res & 0b1000010000100001) == 0b1000010000100001 { return true; } if (res & 0b0001001001001000) == 0b0001001001001000 { return true; } return false; } fn is_forced_win(history: &mut ) fn main() { let temp = read_to_string(stdin()).unwrap(); let mut chars = temp.chars(); let mut next_char = || { let mut c = chars.next().unwrap(); while c.is_whitespace() { c = chars.next().unwrap(); } c }; while next_char() == '?' { let s = (0..SIZE).map(|_| next_char()).collect::>(); let tk = tokenize(&s); } }