Hextrategy ヒーロー勢力のマップ戦略プログラム一応完成した、


2018年 9月12日
 
 
 なんと更新が 1ヶ月以上も伸びてしまいました。

 とにかく暑くてダウンしてました、冷房あっても暑い時はダメですね、赤外線とかなんでしょうか?

 運動もできなくて体がなまりますしね。
 
 
 さて、ようやく CPUヒーロー勢力のアルゴリズムが一応形になりました。

 
 
 これだけじゃ何やってるのか分からないと思うけど、まず右上の緑が左下に攻め込んで負け、下真ん中の紫が隣に攻め込んで勝ち、左下の赤が攻め込んで勝ち。

 HEX内の mp=その国の戦力、hdは現在処理中の勢力の隣接国の脅威値、真ん中の赤いのはマップNo.。

 HEXの枠に色の付いてるのがヒーロー勢力で、無いのは中立国でジッとしてるだけで攻め込まない。

 問題なのは自国と隣国の戦力評価と残戦力比較、攻め込んだ後の再配置とか、今回も結構大変だった。


 
 
 では CPU勢力のアルゴリズムソースを。

*strategy ; 英雄勢力の人材とアイテムの発見と配置、戦略

	repeat plb : pn=hap(cnt)
	 if pn=0 : continue ; 順列に無い
	 if hf(pn)=0 : continue ; 勢力が滅んでる


; 人材とアイテムの発見

	 repeat 25,1 : m=cnt
	  if mpl(m)!pn : continue		; 勢力国では無い
	  un_fd m						; 人材発見
	   if un>0 : hper_set pn,un		; 順列セット
	  it_fd m						; アイテムの発見
	   if in>0 : hiper_set pn,in	; 順列セット
	 loop

	 if hf(pn)=1 : gosub *map_main : continue ; プレイヤー


; 隣接国脅威値を算出

	 repeat 25 : hdp(cnt)=0 : hdn(cnt)=0 : loop; 脅威値をリセット

	 repeat 25,1 : m=cnt			; その国の脅威値を評価
	  if mpl(m)!pn : continue		; 勢力国では無い

	  repeat 6,1
	   n=hmv(m,cnt)					; 隣接する国があるか
	   if n=0 : continue			; 地形が無い
	   if mpl(n)=pn : continue		; 勢力国
	   if hdn(m)<mp(n) : hdn(m)=mp(n) ; 一番大きな値
	  loop

	  pn1=m
	  repeat 25 ; 脅威国順列のソート
	   if hdp(cnt)=0 : hdp(cnt)=pn1 : break	; 空白なら入れて終わり
	   if hdn(pn1)<=hdn(hdp(cnt)) : continue ; 値比較
	   pn2=hdp(cnt) : hdp(cnt)=pn1 : pn1=pn2 ; 入れ替え
	  loop
	 loop


	 pmu_rst pn	; ユニット配置解除
	 peq_rst pn ; 装備解除


	 hrs_copy ; 英雄のユニット操作順列コピー
	 his_copy ; 英雄のアイテム操作順列コピー


; 領主の配置

	 hrs5c=0
	 repeat 25,1 : m=cnt ; 領主配置
	  if mpl(m)!pn : continue ; 勢力国では無い
	  repeat hub
	   if hrs5c=hub : break
	   un=hrs5(hrs5c) : hrs5c+
	   if un=0 : continue
	   mu(m*10)=un : hrs_del un : break ; 領主配置
	  loop
	 loop


; 装備と列の順列のセット

	 repeat hub ; 列の順列をリセット
	  hrt1(cnt)=0 : hrt2(cnt)=0 : hrt3(cnt)=0
	 loop

	 hrt1c=0 : hrt2c=0 : hrt3c=0 ; 現在の列の順番をリセット

	 mp1=0 ; 総戦力値リセット

	 repeat hub,1 ; 装備
	  if cnt\2=2 : hrs_eq 2 : if un=0 : hrs_eq 1 : if un=0 : break ; 2回目
	  hrs_eq 1 : if un=0 : hrs_eq 2 : if un=0 : break ; 1と3回目
	 loop


; 国への配置

	 repeat 25,1
	  if mpl(cnt)!pn : continue ; 勢力国では無い
	  mp(cnt)=0 ; 戦力値リセット
	 loop

	 hrt1c=0 : hrt2c=0 : hrt3c=0 ; 現在の列の順番をリセット


	 repeat 3 : cnt3=cnt ; 配備
	  repeat 25 : m=hdp(cnt)
	   if m=0 : break ; 1順終わり
	   if mp(m)>=hdn(m) : continue ; 必要戦力有る

	   knc=m*10+cnt3*3
	   repeat 3,1
	    if cnt=1 { ; 1列目
		 un=hrt1(hrt1c) : if un>0 : mu(knc+1)=un : ud(un*udb+13)=knc+1 : hrt1c+ : mp(m)+=ud(un*udb+27) : continue
		 un=hrt2(hrt2c) : if un>0 : mu(knc+1)=un : ud(un*udb+13)=knc+1 : hrt2c+ : mp(m)+=ud(un*udb+27) : continue
		 un=hrt3(hrt3c) : if un>0 : mu(knc+1)=un : ud(un*udb+13)=knc+1 : hrt3c+ : mp(m)+=ud(un*udb+27) : continue
	    }
	    if cnt=2 { ; 3列目
		 un=hrt3(hrt3c) : if un>0 : mu(knc+3)=un : ud(un*udb+13)=knc+3 : hrt3c+ : mp(m)+=ud(un*udb+27) : continue
		 un=hrt2(hrt2c) : if un>0 : mu(knc+3)=un : ud(un*udb+13)=knc+3 : hrt2c+ : mp(m)+=ud(un*udb+27) : continue
		 un=hrt1(hrt1c) : if un>0 : mu(knc+3)=un : ud(un*udb+13)=knc+3 : hrt1c+ : mp(m)+=ud(un*udb+27) : continue
	    }
	    if cnt=3 { ; 2列目
		 un=hrt2(hrt2c) : if un>0 : mu(knc+2)=un : ud(un*udb+13)=knc+2 : hrt2c+ : mp(m)+=ud(un*udb+27) : continue
		 un=hrt1(hrt1c) : if un>0 : mu(knc+2)=un : ud(un*udb+13)=knc+2 : hrt1c+ : mp(m)+=ud(un*udb+27) : continue
		 un=hrt3(hrt3c) : if un>0 : mu(knc+2)=un : ud(un*udb+13)=knc+2 : hrt3c+ : mp(m)+=ud(un*udb+27) : continue
	    }
	   loop
	   if hrt1(hrt1c)=0 and hrt2(hrt2c)=0 and hrt3(hrt3c)=0 : break ; 全員使った
	  loop
	 loop


; 戦力評価

	 mp2=0
	 repeat 25,1 : m=cnt
	  if mpl(m)!pn : continue ; 勢力国では無い
	  mpck m : mp2+=mp(cnt) ; 戦力値計測
	 loop

	 mp3=mp1-mp2 ; 残戦力値


; 隣接する弱小国の順列

	 repeat 25 : hda(cnt)=0 : loop ; 弱小国の順列をリセット

	 repeat 25,1 : m=cnt
	  if mpl(m)!pn : continue ; 自領で無い

	  repeat 6,1
	   n=hmv(m,cnt)						; 隣接する国があるか
	   if n=0 or map(n)=0 or mpl(n)=pn : continue	; 敵領で無い

	   f=0
	   repeat 25
	    if hda(cnt)=0 : break			; 最後
	    if hda(cnt)=n : f=1 : break		; 既にある
	   loop
	   if f=1 : continue ; 既に順列にある

	   pn1=n
	   repeat 25 ; 弱小国順列のソート
	    if hda(cnt)=0 : hda(cnt)=pn1 : break  ; 空白なら入れて終わり
	    if mp(pn1)>=mp(hda(cnt)) : continue ; 値比較
	    pn2=hda(cnt) : hda(cnt)=pn1 : pn1=pn2 ; 入れ替え
	   loop
	  loop
	 loop


; 攻め込む

	 repeat 25 : hde(cnt)=0 : loop ; 既に攻め込むのに使ったかリセット

	 repeat 25 : m=hda(cnt) ; 攻め込む隣国の弱順列
	  if m=0 : break ; 終わり

	  repeat 6 : hdk(cnt)=0 : loop ; 隣接する自領の強順列のリセット

	  repeat 6,1
	   pn1=hmv(m,cnt)						; 隣接する国があるか
	   if pn1=0 or mpl(pn1)!pn : continue	; 敵領で無い

	   repeat 6 ; 隣接する自領の強順列のソート
	    if hdk(cnt)=0 : hdk(cnt)=pn1 : break  ; 空白なら入れて終わり
	    if mp(pn1)<=mp(hdk(cnt)) : continue ; 値比較
	    pn2=hdk(cnt) : hdk(cnt)=pn1 : pn1=pn2 ; 入れ替え
	   loop
	  loop

	  repeat 6 : am=hdk(cnt) ; 攻め込む
	   if am=0 : break				; 攻め込める国が無い
	   if mp(am)<=mp(m) : continue	; 戦力が足りない
	   if mp3<=hdn(am) : continue	; 攻め込む自国の脅威値が残戦力以上なので攻め込めない

	   f=0 ; 既に攻め込むのに使った国かフラグ
	   repeat 25
	    if hde(cnt)=0 : hde(cnt)=am : break ; 使用済みに登録
	    if hde(cnt)=am : f=1 : break ; 使ってる
	   loop
	   if f=1 : continue

	   kn1=am			; 攻撃側
	   kn2=m			; 防衛側

	   gosub *battle	; 戦闘

	   if btvf<=0 : continue ; 敗北


; 勝利

	   mpl(kn2)=pn

	   clrf=1
	   repeat 25,1
	    if hf(mpl(cnt))=1 : clrf=0 : break ; プレイヤーが残ってる
	   loop
	   if clrf=1 : mainf=6 : break ; GAME OVER

	   repeat 9,1 ; 部隊の移動
	    mu(kn2*10+cnt)=mu(kn1*10+cnt)
	    mu(kn1*10+cnt)=0
	    un=mu(kn2*10+cnt) : ud(un*udb+13)=kn2
	   loop

	   mu(kn2*10)=0 ; 領主の解除
	   mp(kn1)=0	; 戦力値のリセット

	   repeat 3 : cnt3=cnt ; 配備
	    if mp(kn1)>=hdn(kn1) : break ; 必要戦力有る
	    knc=kn1*10+cnt3*3
	    repeat 3,1
	     if cnt=1 { ; 1列目
		  un=hrt1(hrt1c) : if un>0 : mu(knc+1)=un : ud(un*udb+13)=knc+1 : hrt1c+ : continue
		  un=hrt2(hrt2c) : if un>0 : mu(knc+1)=un : ud(un*udb+13)=knc+1 : hrt2c+ : continue
		  un=hrt3(hrt3c) : if un>0 : mu(knc+1)=un : ud(un*udb+13)=knc+1 : hrt3c+ : continue
	     }
	     if cnt=2 { ; 3列目
		  un=hrt3(hrt3c) : if un>0 : mu(knc+3)=un : ud(un*udb+13)=knc+3 : hrt3c+ : continue
		  un=hrt2(hrt2c) : if un>0 : mu(knc+3)=un : ud(un*udb+13)=knc+3 : hrt2c+ : continue
		  un=hrt1(hrt1c) : if un>0 : mu(knc+3)=un : ud(un*udb+13)=knc+3 : hrt1c+ : continue
	     }
	     if cnt=3 { ; 2列目
		  un=hrt2(hrt2c) : if un>0 : mu(knc+2)=un : ud(un*udb+13)=knc+2 : hrt2c+ : continue
		  un=hrt1(hrt1c) : if un>0 : mu(knc+2)=un : ud(un*udb+13)=knc+2 : hrt1c+ : continue
		  un=hrt3(hrt3c) : if un>0 : mu(knc+2)=un : ud(un*udb+13)=knc+2 : hrt3c+ : continue
	     }
	    loop
	    mpck kn1 ; 戦力値計測
	    if hrt1(hrt1c)=0 and hrt2(hrt2c)=0 and hrt3(hrt3c)=0 : break ; 全員使った
	   loop

	   break ; 攻め取った
	  loop

	  if mainf!5 : break
	 loop

	 if mainf!5 : break
	loop

	trn+ ; ターン+

	return

 
 
 hap=ヒーロー勢力の戦力値の弱順列だと思う、弱い順かな。

 人材とアイテムを HEXごとに発見処理。

 自勢力、各 HEX事の隣接国の脅威値を算出。

 装備とユニット配置を一度全解除。

 装備とユニットの順列を操作順列にコピー。

 まず領主を配置。

 ユニットに装備をする。

 その HEXの脅威値に達するまで 3体ずつユニット配置。

 配置してない残戦力を算出 =mp3。

 攻め込めるか、まず隣接する弱小国の順列を作り、弱い所へ攻める。

 攻め込む国の周りに自勢力がいくつあるか調べ、強順列にし、強い国から攻めるようにする。

 一度攻め込んだ国はそのターンはもう攻め込まない。

 残戦力が脅威値以上有る場合に攻め込む。

 戦闘処理をし、負けた場合は変化無し、買ったら部隊を攻め込んだ国に移し、攻め込んだ元の国に残戦力から部隊を再配置する。

 以上。
 
 
 国の戦略アルゴリズムも思っていた以上に複雑で難しいと思った。

 という訳で、これでメインのプログラムは一通りできた、ここからはデバッグと調整、OP、EDとかその他の要素をつける。

 でもまだ最後まで完成できるのかどうか自信がないなあ。
 
 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です