2014年9月22日月曜日

リーグ戦の組み合わせ作成プログラム

;hsp3.21
;league.as 03.12.29
;リーグ戦組み合わせ表
;#include "debug.as"
 font "MS ゴシック",16: objmode 2
 file="league.txt" ;出力ファイル
 mes "チーム数を入力してください。"
 input nteam
 button "OK",*l_ok
*l_reinput
 objsel 0: c=-1: sendmsg objinfo(0,2),177,0,varptr(c)
 repeat: wait 1
  stick c,,1
  if c==32 {
   break
  }
 loop

*l_ok
 if nteam\2|(nteam<4)|(nteam>98) {
  dialog "4~98の偶数を入力してください"
  goto *l_reinput
 }
 cls
 mes "このウィンドウに表示されるのは進捗状況です。"
 mes "結果は"+file+"に出力されます。"
 mes "表は、例えば、第0日の第1試合はチーム0とチーム1が対戦するという意味です"
 mes "途中で終了させても、そこまでの結果は出力されます"
 ;nteam=6   ;チーム数
 days=nteam-1  ;日数
 ngame=nteam/2  ;1日の試合数
 sdim buf,(days*6+2)*(ngame+2)+100
 sdim s,days*6+1
 bsave file,buf,1
 ;↑後のbsaveはファイルがないとエラーになるので、とりあえずファイルを作る
 dim teamA,days,ngame ;第i日第j試合の対戦チームA
 dim teamB,days,ngame ;第i日第j試合の対戦チームB
 dim taisen,nteam,nteam ;対戦済みフラグ
 dim use,days,nteam  ;その日にチームを使ったことのフラグ
 ;taisen初期化(i==jについて1にする)
 repeat nteam: taisen.cnt.cnt=1: loop
 ;表示
 gosub *l_head
 repeat days,1
  if cnt>9 { s=" " } else { s="  " }
  buf+=" 0-"+cnt+s
 loop
 mes buf
 ;メイン
 iday=0
 repeat  ;日付ごとのループ
  title "iday="+iday+" 解数="+nsol
  if flg!=2 {  ;正解が見つかって戻ったのでなければ
   ;第0試合を固定する(常にteamA.iday.0=0)
   c=iday+1
   teamB.iday.0=c ;0の相手は常にiday+1
   use.iday.0=1: use.iday.c=1: taisen.0.c=1: taisen.c.0=1
   base=1: igame=1
   ;第1試合以降
  }
  repeat ;1試合ごとのループ
   await
   if flg!=2 { ;次の試合から戻ったのでなければ
    ;teamAを探す(使ってないだけで十分)
    flg=0
    repeat: if base>=nteam {
     break
    }
     if use.iday.base==0 {
      flg=1
      a=base ;仮のteamA
      break
     }
     base++
    loop
   }
   if flg { ;teamAが見つかったとき
    flg=0
    ;teamBを探す(使っていず、aと対戦していないチーム)
    repeat: base++: if base>=nteam {
     break
    }
     if use.iday.base==0 { if taisen.a.base==0 {
      flg=1
      break
     } }
    loop
    if flg { ;teamBが見つかったとき
     teamA.iday.igame=a
     teamB.iday.igame=base
     use.iday.a=1: use.iday.base=1
     taisen.a.base=1: taisen.base.a=1
     ;表示
     x=iday*48+8: y=igame*16+96
     color 255,255,255: boxf x,y,x+40,y+15
     color: pos x,y: mes ""+a+"-"+base
     ;次の試合の準備
     igame++
     if igame>=ngame {
      break
     }
     base=a+1 ;次の試合のteamAはこの試合のteamAの次から探す
     ;↑この試合のteamBに使えなくても次の試合のteamAには
     ;↑使えるかもしれない。
    } else { ;teamBが見つからなかったとき
     base=a+1 ;この試合のteamAを探し直す
    }
   } else {  ;teamAを終わりまで調べたとき
    igame--
    if igame>=1 {
     ;前の試合に戻る
     gosub *l_clrgame
    } else {
     iday--
     if iday>=0 {
      ;前の日の最後の試合に戻る
      igame=ngame-1
      gosub *l_clrgame
     } else {
      buf="組み合わせ数="+nsol+"\n"
      l=strlen(buf)
      bsave file,buf,l,fp
      pos 0,ngame*16+112: mes "組み合わせ数="+nsol
      mes "終了しました"
      stop
     }
    }
   }
  loop
  iday++
  if iday>=days {  ;正解発見
   gosub *l_head
   i=0
   repeat ngame
    repeat days
     if teamA.cnt.i>9 { s=" " } else { s="  " }
     if teamB.cnt.i>9 { t="-" } else { t="- " }
     buf+=s+teamA.cnt.i+t+teamB.cnt.i
    loop
    buf+="\n"
    i++
   loop
   buf+="\n"
   l=strlen(buf)
   bsave file,buf,l,fp: fp+=l
   nsol++
   ;最終日の最後の試合に戻る
   iday--
   igame=ngame-1
   gosub *l_clrgame
  }
 loop
end  ;ここには来ない

*l_head
 buf="": s=""
 repeat days
  if cnt>9 { t="  " } else { t="   " }
  buf+=t+cnt+"  "
  s+="------"
 loop
 buf+="\n"+s+"\n"
return

*l_clrgame
 flg=2
 ;別のteamBを探す
 a=teamA.iday.igame
 base=teamB.iday.igame
 ;useとtaisenを戻す
 use.iday.a=0: use.iday.base=0
 taisen.a.base=0: taisen.base.a=0
return

 ;試し表示
 iday=0: base=0
 repeat days
  n=base
  repeat ngame
   teamA.iday.cnt=n: n++
   teamB.iday.cnt=n: n++
   if n>9 {
    n=0
   }
  loop
  iday++: base+=2: if base>9 {
   base=0
  }
 loop
 mes "  0  1  2  3  4  5  6  7  8"
 mes "---------------------------"
 i=0: y=32
 repeat ngame: x=0
  repeat days
   pos x,y: mes " "+teamA.cnt.i+teamB.cnt.i
   x+=24
  loop
  i++: y+=16
 loop
stop
8チーム以上だと遅くなります

0 件のコメント:

コメントを投稿