use std::{ collections::HashMap, io::{stdin, stdout, Write}, }; const H: usize = 60; const W: usize = 25; // type Output = Vec; fn main() { let mut sim = Sim::new(); for _ in 0..1000 { if let Some(input) = read_input() { if !sim.is_defeat { sim.proceed(input.es, 'S'); println!("S"); stdout().flush().unwrap(); } } else { break; } } eprintln!("score = {}", sim.score); } fn read_input() -> Option { let mut n = String::new(); stdin().read_line(&mut n).unwrap(); if n == "-1" { return None; } let n = n.trim().parse::().unwrap(); let mut es = vec![]; for _ in 0..n { let mut line = String::new(); stdin().read_line(&mut line).unwrap(); let mut tokens = line.split_whitespace(); let h = tokens.next().unwrap().parse::().unwrap(); let p = tokens.next().unwrap().parse::().unwrap(); let x = tokens.next().unwrap().parse::().unwrap(); es.push((h, p, x)); } Some(Input { n, es }) } #[allow(dead_code)] #[derive(Debug)] struct Input { n: usize, es: Vec<(i64, i64, usize)>, } #[derive(Debug, Clone, Copy)] pub struct Player { s: i64, pos_x: usize, } impl Player { pub fn new() -> Self { Player { s: 0, pos_x: 12 } } pub fn level(&self) -> i64 { 1 + self.s / 100 } } impl Default for Player { fn default() -> Self { Self::new() } } struct Enemy { hp: i64, dameged: i64, power: i64, } impl Enemy { pub fn new(hp: i64, power: i64) -> Self { Self { hp, dameged: 0, power, } } } pub struct Sim { board: Vec>, player: Player, enemies: HashMap, score: i64, is_defeat: bool, } impl Sim { pub fn new() -> Self { let mut board = vec![vec![Square::EMPTY; W]; H]; board[0][12] = Square::PLAYER; let player = Player::new(); let enemies = HashMap::new(); Self { board, player, enemies, score: 0, is_defeat: false, } } pub fn proceed(&mut self, es: Vec<(i64, i64, usize)>, command: char) { // 全enemyが一段下に for h in 0..H { for w in 0..W { if let Square::ENEMY { id: _ } = self.board[h][w] { if h != 0 { if Square::PLAYER == self.board[h - 1][w] { self.is_defeat = true; } self.board[h - 1][w] = self.board[h][w]; } self.board[h][w] = Square::EMPTY; } } } // 新たなenemyが出現 for (h, p, x) in es { let id = self.enemies.len() + 1; self.board[H - 1][x] = Square::ENEMY { id }; self.enemies.insert(id, Enemy::new(h, p)); } // playerが移動 match command { 'L' => { let prev_x = self.player.pos_x; let next_x = (self.player.pos_x + W - 1) % W; if let Square::ENEMY { id: _ } = self.board[0][next_x] { self.is_defeat = true; } else { self.board[0][next_x] = self.board[0][prev_x]; } self.board[0][prev_x] = Square::EMPTY; self.player.pos_x = next_x; } 'R' => { let prev_x = self.player.pos_x; let next_x = (self.player.pos_x + W + 1) % W; self.player.pos_x = next_x; if let Square::ENEMY { id: _ } = self.board[0][next_x] { self.is_defeat = true; } else { self.board[0][next_x] = self.board[0][prev_x]; } self.board[0][prev_x] = Square::EMPTY; self.player.pos_x = next_x; } 'S' => {} _ => unreachable!(), } // playerによる攻撃 if !self.is_defeat { for h in 1..H { if let Square::ENEMY { id } = self.board[h][self.player.pos_x] { let enemy = self.enemies.get_mut(&id).unwrap(); enemy.dameged += self.player.level(); if enemy.hp <= enemy.dameged { self.player.s += enemy.power; self.score += enemy.hp; self.enemies.remove(&id); self.board[h][self.player.pos_x] = Square::EMPTY; } break; } } } } } impl Default for Sim { fn default() -> Self { Self::new() } } #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] pub enum Square { PLAYER, ENEMY { id: usize }, EMPTY, }