{*********************************************************************
 *  *** 三山くずし ***                                               *
 *                                                                   *
 *     3つの山にいくつかの石がある。あなたとコンピュータが交互に     *
 *     どこかの山からいくつかの石を取っていく。最後の石を取った      *
 *     方が勝ち。このゲーム、先手必勝です。あなたは先手です。　　　　*
 *     でも勝つ規則を知らなければ絶対に勝てないし、規則を知って      *
 *     いたら馬鹿らしくてゲームにならないでしょう。                  *
 *                                                                   *
 *        HAPPyのサンプルプログラム                                  *
 *          (作者  浅野比富美 Public Domain Software)                *
 *********************************************************************}

program Mitsuyama(input,output) ;

  const  StoneNum = 50    ;             { 3つの山の最初の石の数 }
         YOU      = true  ;             { あなたの番            }
         COM      = false ;             { コンピュータの番      }

  type   YamaRange = 1..3 ;             { 山番号の範囲 }

  var    YOUorCOM : Boolean ;                         { YOU または COM  }
         yama     : array[YamaRange] of 0..StoneNum ; { 3つの山         }
         i        : YamaRange ;                       { for文の制御変数 }

{**********************************}
{* n1,n2の排他的論理和を求める関数*}
{**********************************}
  function nimsum(n1,n2:integer) : integer ;
    var s,m,k,l : integer ;
  begin
    s := 0 ;
    if n1>n2 then m:=n1                 { n1,n2の大きい方をmに }
             else m:=n2 ;
    k:=1 ;
    while m>k do k:=k*2 ;               { mより大きい2のべき乗をk }
    repeat
      l:=0 ;                                          { 0 0 -> 0 }
      if n1>=k then begin n1:=n1-k ; l:=k    end ;    { 0 1 -> 1 }
      if n2>=k then begin n2:=n2-k ; l:=k-l  end ;    { 1 0 -> 1 }
      s:=s+l ;                                        { 1 1 -> 0 }
      k:=k div 2
    until n1=n2 ;                       { n1=n2ならば それ以降の和は0だから }
    nimsum := s
  end {nimsum} ;

{**********************************}
{*    3つの山の石数を出力する     *}
{**********************************}
  procedure printstone ;
    var i : YamaRange  ;
  begin
    writeln ;
    for i:=1 to 3 do write(i:4,'山=',yama[i]:3)
  end {printstone};

{*************************************}
{*    石を取る(残り石がある時は真)   *}
{*************************************}
  function getstone(YOUorCOM : Boolean) : Boolean ;
    var ok      : Boolean ;
        yamaNo  : integer ;             { 取る山の番号 }
        HowMany : integer ;             { 取る石の数   }
        N       : integer ;             { 3つの山の排他的論理和 }
  begin
    if YOUorCOM = YOU then              { あなたが石を取る番 }
    begin
      ok := false ;                     { どの山からいくつ取るか入力する }
      repeat
        printstone ;
        write('  どこから いくつ ? ') ;
        readln(yamaNo,HowMany) ;
        ok := (1<=yamaNo) and (yamaNo<=3)  ;
        if ok then ok := (1<=HowMany) and (HowMany<=yama[yamaNo])
      until ok ;
    end
    else {YOUorCOM = COM}               { コンピュータが石を取る番 }
    begin
      N := nimsum(nimsum(yama[1],yama[2]),yama[3]) ;
      if  N = 0 then                   { 相手が必勝パターンの時    }
      begin                            { 最も多い山から1個だけ取る }
        if      (yama[1] > yama[2]) and (yama[1] > yama[3]) then yamaNo:=1
        else if (yama[2] > yama[3])                         then yamaNo:=2
        else                                                     yamaNo:=3 ;
        HowMany := 1
      end
      else                              { コンピュータが必勝パターンの時 }
      begin
        yamaNo := 1 ;                   { 必勝パターンとなる山と数を見つける }
        while nimsum(N,yama[yamaNo]) >= yama[yamaNo] do yamaNo:=yamaNo+1 ;
        HowMany := yama[yamaNo]-nimsum(N,yama[yamaNo])
      end ;
      printstone ;
      writeln('  ｺﾝﾋﾟｭｰﾀは',yamaNo:1,'山から',HowMany:3,'個取ります')
    end ;
    yama[yamaNo] := yama[yamaNo] - HowMany ;   { 石を取る }
    getstone := (yama[1]+yama[2]+yama[3] <> 0) { 石が全部なくなったら  偽 }
  end {getstone} ;

{**********************************}
{*      メイン処理                *}
{**********************************}
begin
  for i:=1 to 3 do yama[i] := StoneNum ;
  YOUorCOM := YOU ;                     { あなたが先攻です }
  while getstone(YOUorCOM) do YOUorCOM := not YOUorCOM ;
  if YOUorCOM  = YOU then writeln('あなたの勝ち')
                     else writeln('コンピュータの勝ち')
end.
