101 lines
2.3 KiB
Rust
101 lines
2.3 KiB
Rust
use std::io::{read_to_string, stdin};
|
|
|
|
const SIZE: usize = 16;
|
|
const SIDE: usize = 4;
|
|
fn tokenize(s: &Vec<char>) -> 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<u32> {
|
|
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::<Vec<_>>();
|
|
let tk = tokenize(&s);
|
|
}
|
|
}
|