/ICFP2011

ICFP Programming Contest 2011 repository

Primary LanguageHaskell

Team: atomically $ save Madoka

## Team Member and their major role:

- Hiroshige Hayashizaki (@akane_magica)
  supreme tuning on LTG machine language
- Shun Sakuraba (@chunjp)
  the bridge of abstract and machine level;
  wrote both commentful Haskell codes and SKIful LTG codes
- Takayuki Muranushi (@nushio)
  wrote the tournament system and the simulation validator
- Hideyuki Tanaka (@tanakh)
  wrote the LTG Monad and the simulator
  
## Used Programming Languages:

- Haskell (all purpose)

- Ruby (scripting)
- Ocaml (for some searching)

## The source codes

   src/Makefile           The makefile
   src/*.hs               AIs
   src/LTG/Base.hs        Definitions for LTG cards
   src/LTG/Exception.hs   Handles for error/recovery mechanism
   src/LTG/Monad.hs       The LTG Monad
   src/LTG/Simulator.hs   The built-in game simulator
   src/LTG/SoulGems.hs    Building blocks library for AI strategies
  
  
## About Our Solution:

- We implemented a DSL for programming LTG playing AIs (artificial
  intelligences) in Haskell.

- The core of the language is the LTG monad. We can write LTG AIs by
  composing the LTG monad. When we `runLTG :: LTG a -> IO ()` the
  monad, it returns a executable program for the LTG. With LTG Monad
  we can describe wide hierarchy of abstractness: from the raw
  sequence of highly-tuned raw-level instructions, to human readable
  strategic instructions (such as 'attack these range' or 'summon
  zombie').

  Such high-level library functions provides safeness, robustness and
  speed. For example, user can build complex strategies and when it
  fails at any point (e.g. the slot it uses is accidentally dead) it
  can safely fall back to recovery. Other functions, such as 'set a
  numeric value to the slot' will performed number construction, so
  that it re-uses partially build numbers from the slot and other
  slots, and it automatically revives the target slot if it's dead.

  The game simulator is integrated within the DSL, So that our AI can
  know the current and past state of the game clearly. Also the
  programmer can instruct the built-in simulator to record the game to
  a file, so that we can understand how our AIs are doing.
   
  All of these features are seamlessly composable, and independently
  extensible.
  

- Our main strategy "Kyoko" series, "Y2CAtkQb" being the final
  product, is to send a zombie to the opponent that issues many 'Help
  i i n' instructions in sequence while incrementing index i. Each of
  the instruction can kill a slot with vital in range [n .. 2.1n].
  Generally, a single zombie issue can kill over ~50 slots.

  And she's really, really fast. She can summon the first zombie in
  136 turns and can kill a "Sitting Duck" (an AI that does nothing) in
  186 turns. She can overwhelm most other strategies just by this
  speed.
  
  The construction process of the zombie is complex, and is prone to
  interceptions from the opponents. Thanks to the accurate simulation
  of the game state and the error handling mechanism, our AI is robust
  against such interceptions. If she detects an error (such as a slot
  being used for construction is killed) she immediately fall-backs to
  a recovery mode, revive the slots, and then re-start the
  construction. At the second run, she uses the caching mechanism:
  she searches for the sub-expressions of the expression she wants to
  build, and try to re-use what she can find on the memory (most
  possibly the immature results of previous disrupted construction.)
  With caching, our AI can issue the second attack really fast too,
  even when the first attack fails.
  
  We noticed the importance and speciality of the slot 0 at the early
  stage of the contest. Although our AIs need to use slot 0
  frequently, the life-time needed for Slot 0 is minimized. One of the
  building-block function "lazyApply" applies a function on slot f1 to
  a value on slot f2 (f1, f2 /= 0) using slot 0 as a work area. It
  requires that slot 0 is kept alive only for several turns. The slot
  0 is occupied about the half of the time until the zombie is ready,
  but the use of slot 0 is in many tiny time segment, so that when the
  construction process is interrupted, the AI goes to recovery mode
  and then resumes the process.
                 
- We also wrote a team-local contest hosting system. Thanks to
  Haskell's powerful and safe parallel programming capability, we
  could easily write the contest system that can hold hundreds of LTG
  match in parallel on a 64-core distributed computer system.
  
  The contest system used remote procedure call (RPC) library
  msgpack-rpc and software transactional memory (STM) library from the
  Hackage.

  
P.S.

  We enjoyed the contest very much!
  Thank you for the interesting problem!