Hextrategy やっと戦略アルゴリズムができた


2019年 6月 22日

 や、やっとできた。

 建築と政府の実装要素を入れた戦略アルゴリズム、なんと 3ヶ月もかかった。

 むずかし~い、今回は改めて思ったけど、初心者は 1MAPゲームとか STGのような単純なゲームを作るのを心がけた方が良いね。

 戦略のプログラムは予想以上に頭がこんがらがる、慣れもあるんだろうけど、これはコーエーが戦略ゲーム独占なのもうなずけるかな。

 STGだと当たり判定のような数学的な難しさはあるけど、一度出来てしまえば後は繰り返しなので、ある意味そんなに難しく無い。

 しかしこの戦略は、色々な要素をどんな順番でどう評価して動かすか、これはもう頭使う。

 はじめの頃に書いたけど、ゲームプログラムの難しさ 1MAP → ADV・STG → RPG → SLG だと思う。

 収入も無いのに、もう丸 2年も時間を使ってしまって、これは失敗だったと考えてる。

 みなさんはもう少し完成の目処の立つ簡単な作品を完成させて行く事をお勧めします。

 少しずつステップアップするのが良いと思います。
 
 

 さて、途中経過を「難しい、完成しない」と言って書いてると「精神論なんかいらねえんだよクズ!」という人がいるみたいなので、今回は途中経過を一切書かなかった。

 でも流石に更新の間が開きすぎてるので、これからはまた途中経過を記事にする事にする。

 しかしねえ、実際にやってみると適性もあるのかもしれないけど、プログラムだけでも相当大変だよ。
 
 
 まだ一応一通り動いただけで、バグ取りはこれからなのだが、あっという間に時間が過ぎて更新が空き過ぎるので、ここで一回発表する事にした。
 
 
 すこしだけ見てみる


 
 
 隣接する国で、一番弱い国を攻める

 HEXの上の数字は戦力値。

 脅威の無い国は配備無し、隣接する脅威値に応じて戦力配備する。

 これバグだけど赤国の上の HEXの城が消えてる。
 
 
 人員に余裕があると政府配置してくれる、これはデバッグ表示だが、政府の所

 左は部隊配備、wp1はその勢力の総戦力、wp4は必要な総防衛力、wpnは攻めるのに必要な戦力、wpbは隣接する敵国の戦力
 
 
 戦力が足りないときは TALENTを引い人員を補充してくれる。

 この画面は確認のためで、CPUはいずれ表示はしないようにする。
 
 

 右の赤国に警察署が建設された。

 という辺りで概要は終わりにする。
 
 
 
 それではソースの解説をする。

 メインソースはこんな感じになった

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

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

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

	 str_map_put	; マップ表示

	 dependent_set	; 一時属領一覧セット
	 mana_point		; マナポイント
	 un_it_found	; ユニットとアイテムの発見

	 ;wpb_cal		; 最大脅威値算出


; プレイヤー

	 if hf(pn)=1 {
	  gosub *map_main

	  hdb(pn)=0 ; 最大戦力値の算出
	  repeat 9 : hdb_un(cnt)=0 : loop

	  repeat pubn(pn),udsh(pn) : un1=cnt
	   if ud(un1*udb)=0 : continue ; ユニットNo.
	   repeat 9 ; 大きいのに入れ替え
	    if hdb_un(cnt)=0 : hdb_un(cnt)=un1 : break
	    if ud(hdb_un(cnt)*udb+27)>ud(un1*udb+27) : continue
	    un2=hdb_un(cnt) : hdb_un(cnt)=un1 : un1=un2
	   loop
	  loop
	  repeat 9
	   hdb(pn)+=ud(hdb_un(cnt)*udb+27)
	  loop
;hdb_put
	  continue
	 }


; CPU

	 ;eq_setn=0		; 装備種別カウント

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

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

	 mpn234_per		; 魔術、マナ、治安の順列

; 仮配備
	 hrt1c=0  : hrt2c=0  : hrt3c=0	; 列の順番カウントをリセット
	 hrt1qc=0 : hrt2qc=0 : hrt3qc=0	; 装備列の順番カウントをリセット

	 human_set		; 人材
	 blacksmith_set	; 鍛冶
	 castle_set		; 城配備

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

	 hdn_cal		; 隣接国脅威値を算出
	 attack_point	; 攻勢点

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

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

	 hrt1c=0  : hrt2c=0  : hrt3c=0	; 列の順番カウントをリセット
	 hrt1qc=0 : hrt2qc=0 : hrt3qc=0	; 装備列の順番カウントをリセット

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

	 mpn234_per		; 魔術、マナ、治安の順列

	 human_set		; 人材
	 blacksmith_set	; 鍛冶
	 castle_set		; 城配備


; 戦力が足りない
	  if matp=0 {;: not_enough : break

	   repeat 25 : st_cnt=cnt ; 戦力配備
	    if hdp(cnt)=0 : break
	     haibi hdp(cnt),3 : if haibif=1 : break
	   loop
	   ;if haibif=0 : break ; 終わり

	   ;stnf=0
	   repeat 25 ; 外交館建設要請
	    m=hdp(cnt) : if m=0 : break
	    if hdn(m)<=wp(m) : continue ; 戦力が足りてる
	    mdg=m*mdb
	    if md(mdg+7)>0 or md(mdg+9)!0 : continue
	    md(mdg+9)=10
	    /*
	    if bul_mp(10)<pmp(pn) /*: stmf=1*/ ;: break ; マナが足りない
	    ; md(mdg+7)=10 : pmp(pn)-=bul_mp(10) ; 外交館建設
	   loop
	   ;if stmf=1 : return ; 終わり

	   talent_set pn ; タレント発掘
	   build_syo ; 建設処理
	   ;continue
	  }


; 戦力が足りてる

	 if matp>0 {

	 switch hdkn ; 攻める国数

	  case 1 ; 1国
	   m=hdk(0)
	    haibi m,hdfn :; hdp_del m ; 第一攻勢国、配備


	   if wp(m)<wp(matp)*2   : swbreak ; 必要戦力が無い
	   war m,matp ; 攻める
	  swbreak

	  case 2 ; 2国
	   m1=hdk(0) : haibi m1,hdfn : ;hdp_del m1 ; 第一攻勢国、配備
	    if wp(m1)*10<wp(matp)*12 : swbreak ; 必要戦力が無い
	   m2=hdk(1) : haibi m2,hdfn : ;hdp_del m2 ; 第二攻勢国、配備
	    if wp(m2)*10<wp(matp)*8  : swbreak ; 必要戦力が無い

	   war m1,matp ; 攻める
	   	win_syorif=2 : swbreak ; 勝った

	   war m2,matp ; 攻める
	  swbreak

	  case 3 ; 3国
	   m1=hdk(0) : haibi m1,hdfn : ;hdp_del m1 ; 第一攻勢国、配備
	    if wp(m1)*10<wp(matp)*10 : swbreak ; 必要戦力が無い
	   m2=hdk(1) : haibi m2,hdfn :; hdp_del m2 ; 第二攻勢国、配備
	    if wp(m2)*10<wp(matp)*8  : swbreak ; 必要戦力が無い
	   m3=hdk(2) : haibi m3,hdfn : ;hdp_del m3 ; 第三攻勢国、配備
	    if wp(m3)*10<wp(matp)*6  : swbreak ; 必要戦力が無い

	   war m1,matp ; 攻める
	   	win_syorif=2 : swbreak ; 勝った

	   war m2,matp ; 攻める
	   	win_syorif=2 : swbreak ; 勝った

	   war m3,matp ; 攻める
	  swbreak

	 swend

	 dependent_set	; 一時属領一覧セット

	 matp=0			; 攻勢国リセット
	 hdn_cal		; 隣接国脅威値を算出

	 ;equipment_set	; 装備と列の順列のセット
	 force_set		; 部隊配備

	  if haibif=1 : talent_set pn ;: continue ; ユニット足りない

	 }

	 stmf=0 ; 戦略モードフラグ

	 police_set		; 警察要請
	 diplomacy_set	; 外交要請


	 government_set	1	; 政府

	 mana2_set	; 第二マナ地
	 magic2_set	; 第二魔術地
	 market_set	; 市場

	 build_syo	; 建設処理


	 repeat 25,1 : m=cnt ; 領主配備
	  if map(m)=0 or mpl(m)!pn : continue
	  if mu(m*10)>0 : continue ; 配備してる

	  hrs_pic 5		; un選択
	  rh_eq un,4	; 装備
	  mu(m*10)=un : ud(un*udb+13)=m*10 ; 配備
	 loop


	 government_set	0	; 政府


	 if mainf!5 : break
	loop

	trn+ ; ターン+

	return

 
 
 最初の repeat plbはプレイヤー最大数の事。

 dependent_set ; 一時属領一覧セット
  mpn(pn)という変数にその勢力の(pn = プレイヤーNo.)占領している国を入れる。

 mana_point ; マナポイント
  属領から上がるマナポイントを加算。

 un_it_found ; ユニットとアイテムの発見
  属領から発見されるユニットとアイテム。

 プレイヤーの部分はプレイヤーが手動操作する国で、そちらへジャンプするので今回は関係ない。

  pmu_rst pn ; ユニット配置解除
  peq_rst pn ; 装備解除
  まずその勢力の全てのユニットと装備を全解除します。

 hrs_copy ; 英雄のユニット操作順列コピー
 his_copy ; 英雄のアイテム操作順列コピー
  その勢力のユニットとアイテムの順列を操作用の一時変数順列にコピーします。

mpn234_per ; 魔術、マナ、治安の順列
  属領のデータ、2=魔術、3=マナ、4=治安の順列をつくります。

#deffunc mpn234_per ; 魔術、マナ、治安の順列

	repeat 25
	 mpn2(cnt)=0 ; 魔術の順列リセット
	 mpn3(cnt)=0 ; マナの順列リセット
	 mpn4(cnt)=0 ; 治安の順列リセット
	loop

	repeat 25 ; 魔術の順列
	 m=mpn(cnt) : if m=0 : break
	 repeat 25 ; ソート
	  if mpn2(cnt)=0 : mpn2(cnt)=m : break
	  if md(mpn2(cnt)*mdb+2)>md(mpn2(m)*mdb+2) : continue
	  n=mpn2(cnt) : mpn2(cnt)=m : m=n
	 loop
	loop

	repeat 25 ; マナの順列
	 m=mpn(cnt) : if m=0 : break
	 repeat 25 ; ソート
	  if mpn3(cnt)=0 : mpn3(cnt)=m : break
	  if md(mpn3(cnt)*mdb+3)>md(mpn3(m)*mdb+3) : continue
	  n=mpn3(cnt) : mpn3(cnt)=m : m=n
	 loop
	loop

	repeat 25 ; 治安の順列
	 m=mpn(cnt) : if m=0 : break
	 repeat 25 ; ソート
	  if mpn4(cnt)=0 : mpn4(cnt)=m : break
	  if md(mpn4(cnt)*mdb+4)<md(mpn4(m)*mdb+4) : continue
	  n=mpn4(cnt) : mpn4(cnt)=m : m=n
	 loop
	loop

	return

 
 
human_set ; 人材
 人材を発掘する用の国を 1つ選びます。

#deffunc human_set ; 人材

	 repeat 25 : m=mpn3(cnt) ; 第一人材地の選定
	  if m=0 : continue
	  mdg=m*mdb
	   if md(mdg+7)=8 or md(mdg+7)=10 : continue	; 警察、外交館
	   if md(mdg+4)<90000 : continue				; 治安が足りない
	   ;if md(mdg+7)=1 or md(mdg+7)=5 : break		; 城、人材府
	   break
	 loop

	 if m>0 { ; 人材配置
	  mpn234_del m	; 順列からmNo.消去
	  hrs_pic 4		; un選択、魅力
	  rh_eq un,4	; 魅力装備
	  mu(m*10)=un : ud(un*udb+13)=m*10 ; 配備

	  n=md(mdg+7)
	  repeat 1 ; 建築要請
	   if n=0 {
		if pubsn(pn)<pubsb : md(mdg+9)=5 : break ; 人材府建築要請
		repeat 25,1 : m=cnt : mdg=m*mdb	; 人材府が最大の時、解体する弱小国
		 if md(mdg+7)!5 : continue
		 if n=0 : n=m : continue
		 if md(mdg+3)<md(n*md+3) : n=m	; 再弱国
		loop
		md(n*mdb+9)=-1 : break			; 解体要請
	   }
	   if n=1 or n=5 or n=10 : break	; 城、人材府、外交府
	   md(mdg+9)=-1						; 解体要請
	  loop
	 }

	return

 
 
blacksmith_set ; 鍛冶
 アイテムを発見する用の国を 1つ選びます。

#deffunc blacksmith_set ; 鍛冶

	repeat 25 : m=mpn2(cnt) ; 第一鍛冶地の選定
	 if m=0 : continue
	 mdg=m*mdb
	  if md(mdg+7)=8 or md(mdg+7)=10 : continue	; 警察、外交館
	  if md(mdg+4)<90000 : continue				; 治安が足りない
	  ;if md(mdg+7)=5 or md(mdg+9)=5 : continue		; 人材地
	  break
	loop

	if m>0 { ; 人材配置
	 mpn234_del m	; 順列からmNo.消去
	 hrs_pic 3		; un選択、知力
	 rh_eq un,3		; 知力装備
	 mu(m*10)=un : ud(un*udb+13)=m*10 ; 配備

	 n=md(mdg+7)
	 repeat 1 ; 建築要請
	  if n=0 : md(mdg+9)=6 : break	; 鍛冶建築要請
	  if n=1 or n=6 or n=10 : break	; 城、人材府、外交府
	  md(mdg+9)=-1					; 解体要請
	 loop
	}

	return

 
 
castle_set ; 城配備
 これはユニットとアイテムの 1番の国が城のある本国だった場合、だったかな?

#deffunc castle_set ; 城配備

	m=mpc(pn) : mdg=m*mdb
	if mu(m*10)=0 { ; 配備してない

	 chaibif=0
	 repeat 1
	  if md(mdg+4)<=90000 : chaibif=1 : break ; 筋力

	  repeat 25 ; 第二人材地
	   if mpn2(cnt)=0 : continue
	   m2=mpn2(cnt) : break
	  loop
	  if m=m2 : chaibif=4 : break ; 魅力

	  repeat 25 ; 第二鍛冶地
	   if mpn3(cnt)=0 : continue
	   m2=mpn3(cnt) : break
	  loop
	  if m=m2 : chaibif=3 : break ; 知力

	  chaibif=4 ; 魅力
	 loop

	 mpn234_del m		; 順列からmNo.消去
	 hrs_pic chaibif	; un選択
	 rh_eq un,chaibif	; 装備
	 mu(m*10)=un : ud(un*udb+13)=m*10 ; 配備
	}

	return

 
 
equipment_set1 ; 仮装備、装備と列の順列のセット
仮装備してその勢力の最強部隊戦力値(wpb)を出します。

#deffunc equipment_set1 ; 仮装備、装備と列の順列のセット

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

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

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


	es1n=0
	repeat hub ; 装備
	 ;es1n+ : if es1n=10 : break
	 if es1n\3=2 { ; 2回目
	  hrs_eq 2 : if un=0 : hrs_eq 1
	  continue
	 }
	 hrs_eq 1 : if un=0 : hrs_eq 2 ; 1と3回目
	loop


; 最大脅威値(最強部隊)算出

	hdb(pn)=0 : n=0
	repeat 10
	 un=hrt1(cnt) : if un>0 : hdb(pn)+=ud(un*udb+27) : n+ : if n>=9 : break
	 un=hrt2(cnt) : if un>0 : hdb(pn)+=ud(un*udb+27) : n+ : if n>=9 : break
	 un=hrt3(cnt) : if un>0 : hdb(pn)+=ud(un*udb+27) : n+ : if n>=9 : break	 
	loop

	repeat 25,1 ; MAP最大脅威値
	 if mpl(cnt)!pn : continue
	 wpb(cnt)=hdb(pn)
	loop

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

	return

 
 
hdn_cal ; 隣接国脅威値を算出
 属領の各必要防衛値を出します。
 総数は wp4にまとめられます。

; 隣接国脅威値を算出
#deffunc hdn_cal ; 隣接国脅威値を算出

	repeat 26 ; 脅威値をリセット
	 hdp(cnt)=0	; 脅威国の順列
	 hdn(cnt)=0	; 脅威値
	 ;hdsn(cnt)=0	; 脅威最小値
	 ;hdsp(cnt)=0	; の国
	loop
	 hdfn=0		; の部隊数

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

	 repeat 6,1
	  n=hmv(m,cnt) : if n=0 : continue	; 隣接する国があるか
	  ;if map(n)=0  : continue			; 地形が無い
	  if mpl(n)=pn or mpl(n)=0 : continue; 自領、NPC
if n=matp : continue ; 攻勢国

	  ;if hf(mpl(n))=1 : wp(n)+=10000	; プレイヤー国なら
	  if hdn(m)<wpb(n) : hdn(m)=wpb(n)	; 一番大きな値
	  ;if hdn(m)<wp(n) : hdn(m)=wp(n)	; 一番大きな値
	  ;if hdsn(m)=0 or hdsn(m)>wp(n) : hdsn(m)=wp(n) : hdsp(m)=n ; 一番小さな値の国
	 loop
/*
	 repeat 3 : cnt4=cnt
	  repeat 3,1
	   if mu(hdsp(m)*10+cnt4*3+cnt)>0 : hdfn(m)+ : break ; 部隊がある
	  loop
	 loop
*/
	 pn1=m
	 repeat 25 ; 脅威国順列のソート
	  if hdp(cnt)=0 : hdp(cnt)=pn1 : break	; 空白なら入れて終わり
	  if hdn(pn1)<=hdn(hdp(cnt)) and mpc(pn)!pn1 : continue ; 値比較
	  ;if hdn(pn1)<=hdn(hdp(cnt)) and mpc(pn)!pn1 : continue ; 値比較、首都は一番上
	  pn2=hdp(cnt) : hdp(cnt)=pn1 : pn1=pn2 ; 入れ替え
	 loop
	loop


; 必要総防衛値

	wp4=0
	repeat 25,1
	 if mpl(cnt)!pn or map(cnt)=0 : continue
	 wp4+=hdn(cnt)
	loop

	return

 
 
attack_point ; 攻勢点
 属領に隣接する一番弱い国を一つ選んで攻め込む国を設定します。
 攻める国は matpに格納されます、必要戦力は wpnです。

#deffunc attack_point ; 攻勢点

	matp=0 : wpn=0 ; 攻勢点と戦力値
	hdkn=0 ; 攻められる国の数

	repeat 25 ; 首都調べ
	 m=mpn(cnt) : if m=0 : break

	 repeat 6,1
	  n=hmv(m,cnt) : if n=0 : continue	; 隣接する国があるか

	  repeat 25,1
	   if cnt=pn or mpc(cnt)=0 or mpc(cnt)!n : continue ; 首都では無い
	   if wpn=0 or wpn>wp(n) : wpn=wp(n) : matp=n : break ; 最弱の首都
	  loop
	 loop
	loop
	if wp1-wp4<wpn*2 : matp=0 : wpn=0 ; 首都攻勢点無し


	if matp=0 {
	 wpn=0
	 repeat 25 ; その他の国
	  m=mpn(cnt) : if m=0 : break

	  repeat 6,1
	   n=hmv(m,cnt) : if n=0 : continue	; 隣接する国があるか
	    if map(n)=0 or mpl(n)=pn : continue ; 地形無い、自領
	    if wpn=0 or wpn>wp(n) : wpn=wp(n) : matp=n : continue ; 最弱の国
	  loop
	 loop
	 if wp1-wp4<wpn*2 : matp=0 : wpn=0  : return ; 攻勢点無し
	}
	if matp=0 : return ; 攻勢点無し


	repeat 6 : hdk(cnt)=0 : loop ; 攻める国の順列リセット

	repeat 6,1 ; 攻める国の順列
	 n1=hmv(matp,cnt) : if n1=0 : continue
	 if mpl(n1)!pn : continue ; 自領では無い
	 hdkn+
	 repeat 6 ; ソート
	  if hdk(cnt)=0 : hdk(cnt)=n1 : break
	  if hdn(hdk(cnt))>hdn(n1) : continue ; 小さい順
	  n2=hdk(cnt) : hdk(cnt)=n1 : n1=n2
	 loop
	loop

	repeat 3 : cnt2=cnt ; 部隊数
	 repeat 3,1
	  if mu(matp*10+cnt2*3+cnt)>0 : hdfn+ : break ; 部隊がある
	 loop
	loop

	return

 
 
 ここまでは情報収集のための仮配備だったので、もう一度装備と配備をリセットします。

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

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

hrt1c=0 : hrt2c=0 : hrt3c=0 ; 列の順番カウントをリセット
hrt1qc=0 : hrt2qc=0 : hrt3qc=0 ; 装備列の順番カウントをリセット

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

mpn234_per ; 魔術、マナ、治安の順列
 
 
 今度は実配備になります。

human_set ; 人材
blacksmith_set ; 鍛冶
castle_set ; 城配備
 
 
 防衛戦力が足りない場合は部隊配備と外交官を優先して終わります。

; 戦力が足りない
	  if matp=0 {;: not_enough : break

	   repeat 25 : st_cnt=cnt ; 戦力配備
	    if hdp(cnt)=0 : break
	     haibi hdp(cnt),3 : if haibif=1 : break
	   loop

	   repeat 25 ; 外交館建設要請
	    m=hdp(cnt) : if m=0 : break
	    if hdn(m)<=wp(m) : continue ; 戦力が足りてる
	    mdg=m*mdb
	    if md(mdg+7)>0 or md(mdg+9)!0 : continue
	    md(mdg+9)=10
	    /*
	    if bul_mp(10)<pmp(pn) /*: stmf=1*/ ;: break ; マナが足りない
	    ; md(mdg+7)=10 : pmp(pn)-=bul_mp(10) ; 外交館建設
	   loop
	   ;if stmf=1 : return ; 終わり

	   talent_set pn ; タレント発掘
	   build_syo ; 建設処理
	   ;continue
	  }

 
 
 必要な戦力がある場合は攻勢点(matp国)を攻めます。
 最大自領 3国から攻めるようにしてますけど、バグなのかまだ機能しません。
(なんと if win_syorif=2と書く所を win_syorif=2とだけ書いてました。
 この「if抜け」はプログラムに慣れてくると結構やらかします。
 しかも書いてあるという思い込み前提なので、発見がしにくいという(笑))

; 戦力が足りてる

	 if matp>0 {

	 switch hdkn ; 攻める国数

	  case 1 ; 1国
	   m=hdk(0)
	    haibi m,hdfn :; hdp_del m ; 第一攻勢国、配備


	   if wp(m)<wp(matp)*2   : swbreak ; 必要戦力が無い
	   war m,matp ; 攻める
	  swbreak

	  case 2 ; 2国
	   m1=hdk(0) : haibi m1,hdfn : ;hdp_del m1 ; 第一攻勢国、配備
	    if wp(m1)*10<wp(matp)*12 : swbreak ; 必要戦力が無い
	   m2=hdk(1) : haibi m2,hdfn : ;hdp_del m2 ; 第二攻勢国、配備
	    if wp(m2)*10<wp(matp)*8  : swbreak ; 必要戦力が無い

	   war m1,matp ; 攻める
	   	win_syorif=2 : swbreak ; 勝った

	   war m2,matp ; 攻める
	  swbreak

	  case 3 ; 3国
	   m1=hdk(0) : haibi m1,hdfn : ;hdp_del m1 ; 第一攻勢国、配備
	    if wp(m1)*10<wp(matp)*10 : swbreak ; 必要戦力が無い
	   m2=hdk(1) : haibi m2,hdfn :; hdp_del m2 ; 第二攻勢国、配備
	    if wp(m2)*10<wp(matp)*8  : swbreak ; 必要戦力が無い
	   m3=hdk(2) : haibi m3,hdfn : ;hdp_del m3 ; 第三攻勢国、配備
	    if wp(m3)*10<wp(matp)*6  : swbreak ; 必要戦力が無い

	   war m1,matp ; 攻める
	   	win_syorif=2 : swbreak ; 勝った

	   war m2,matp ; 攻める
	   	win_syorif=2 : swbreak ; 勝った

	   war m3,matp ; 攻める
	  swbreak

	 swend

	 dependent_set	; 一時属領一覧セット

	 matp=0			; 攻勢国リセット
	 hdn_cal		; 隣接国脅威値を算出

	  if haibif=1 : talent_set pn ;: continue ; ユニット足りない

	 }

 
 
force_set ; 部隊配備
 防衛戦力配備をします。

#deffunc force_set ; 部隊配備

	haibif=0
	repeat 3 : cnt3=cnt ; 配備
	 if haibif=1 : break ; 残戦力無し
	 repeat 25 : m=hdp(cnt)
	  if m=0 : break ; 1順終わり
	  if wp(m)>=hdn(m) /*and hdfn(m)<cnt3+1*/ : continue ; 必要戦力有り部隊数が揃ってる

	  haibi m,1 ; 配備
	   if haibif=1 : break ; 残戦力無し
	 loop
	loop

; 戦力評価

	wp2=0 ; 総配備戦力
	repeat 25,1 : m=cnt
	 if mpl(m)!pn : continue ; 勢力国では無い
	 wp2+=wp(cnt) ; 戦力値計測
	loop

	wp3=wp1-wp2 ; 残戦力値

	return

 
 
 内政です。

police_set ; 警察要請
 治安回復のため警察を最優先します。

#deffunc police_set ; 警察要請

	n=0
	repeat 25
	 m=mpn(cnt) : if m=0 : continue
	 if md(m*mdb+4)<90000 : n+
	loop
	if n>=3 : hrs_pic 1 : if un>0 {	; 治安が悪い国3つ以上の時、警察長官任命
	
	 mgv(pn*mgvb+5)=un
	 ud(un*udb+13)=1000+pn*mgvb+5	; 配属場所登録
	}

	repeat 25
	 m=mpn4(cnt) : if m=0 : continue
	 mdg=m*mdb
	  if md(mdg+7)=1 or md(mdg+7)=10 or md(mdg+9)=10 or md(mdg+9)=-1: continue ; 城、外交府
	  if md(ndg+4)>=100000 and md(mdg+7)=8 : md(mdg+9)=-1 : continue ; 解体要請
	  if md(mdg+4)<90000 {
	   if md(mdg+7)>0 : md(mdg+9)=-1 : continue ; 解体要請
	   md(mdg+9)=8	; 建築要請

; 領主配備
	   if stmf=1 : continue ; un無い

	   hrs_pic 1 : if un=0 : stmf=1 : continue ; un選択
	    ;if un=0 : talent_set pn : break ; いない
	   rh_eq un,1	; 装備
	    mu(m*10)=un : ud(un*udb+13)=m*10 ; 配備
	   mpn234_del m	; 順列からmNo.消去
	  }
	loop

	return

 
 
diplomacy_set ; 外交要請
 今見たらプログラムが間違ってますね、機能してません。
 調整しないと。

#deffunc diplomacy_set ; 外交要請

	repeat 25
	 m=hdp(cnt) : if m=0 : break
	 mdg=m*mdb
	  if md(mdg+7)=1 or md(mdg+7)=8 or md(mdg+9)=8 or md(mdg+9)=-1 : continue ; 城、警察
	  if wp(m)>=hdn(m) and md(mdg+7)=10 : md(mdg+9)=-1 : continue ; 解体要請
	  if md(mdg+7)=10 or md(mdg+9)=10 {
	   md(mdg+9)=8 ; 建築要請

; 領主配備
	   if stmf=1 : continue ; un無い

	   hrs_pic 4 : if un=0 : stmf=1 : continue ; un選択
	   rh_eq un,4	; 装備
	    mu(m*10)=un : ud(un*udb+13)=mdg ; 配備
	   mpn234_del m	; 順列からmNo.消去
	  }
	loop

 
 
government_set 1 ; 政府
 政府の配属をします。
 1というのは 3国や 5国以上無いと配備しないモードです。

#deffunc government_set int gv_setf ; 政府
; gv_setf(0=領土数を考慮しない、1=領土数を考慮)

; 首領
	if gv_setf=0 or mpnc>=5 { ; 領有国が5国以上
	 hrs_pic 5 ; 総力
	  if un=0 : stmf=1 : return
	   rh_eq un,4		; 装備
	   mgv(pn*mgvb+1)=un ; 首領
	    ud(un*udb+13)=1000+pn*mgvb+1	; 配属場所登録
	}


	if gv_setf=0 or mpnc>=3 { ; 領有国が3国以上

; 政務
	 hrs_pic 4 ; 魅力
	  if un=0 : stmf=1 : return
	   rh_eq un,4		; 装備
	   mgv(pn*mgvb+2)=un ; 政務
	    ud(un*udb+13)=1000+pn*mgvb+2	; 配属場所登録

; 魔術
	 hrs_pic 3 ; 知力
	  if un=0 : stmf=1 : return
	   rh_eq un,3		; 装備
	   mgv(pn*mgvb+3)=un ; 魔術
	    ud(un*udb+13)=1000+pn*mgvb+3	; 配属場所登録

; 宗教
	 hrs_pic 2 ; 魔力
	  if un=0 : stmf=1 : return
	   rh_eq un,2		; 装備
	   mgv(pn*mgvb+4)=un ; 宗教
	    ud(un*udb+13)=1000+pn*mgvb+4	; 配属場所登録

; 軍務
	 hrs_pic 5 ; 総力
	  if un=0 : stmf=1 : return
	   rh_eq un,1		; 装備
	   mgv(pn*mgvb+6)=un ; 軍務
	    ud(un*udb+13)=1000+pn*mgvb+6	; 配属場所登録

	}

	return

 
 
mana2_set ; 第二マナ地
 人材を発見する第二候補地、マナを伸ばすようにします。
 それからユニット登録が満杯の場合に、人材府を建設します。
 条件が複雑なので非常に苦労したソースですが、まだちゃんと機能するかどうか未確認です。

#deffunc mana2_set ; 第二マナ地

	m2sf=0 ; 満員フラグ
	 if pubn(pn)<=pubg(pn) : m2sf=1 ; 満員

	m2sc=0 ; 配備カウンター
	repeat 25,1 : m=cnt
	 if map(m)=0 or mpl(m)!pn : continue
	 if md(m*mdb+7)!5 or md(m*mdb)=0 : continue
	 m2sc+ ; 配備してる
	loop

	m2sbf=0 ; 建設フラグ
	repeat 25,1 : m=cnt
	 if map(m)=0 or mpl(m)!pn : continue
	 if md(m*mdb+9)=5 : md(m*mdb+9)=0 ; 建設要請リセット
	loop


	repeat 25 : m=mpn3(cnt) ; 人材地の選定
	 if m=0 : continue
	 mdg=m*mdb

	 n=md(mdg+7) ; 建築物
	  if n=1 or n=6 or n=7 or n=8 or n=10 or n=11 : continue
	  ; 城、鍛冶屋、砦、警察、外交館、倉庫

	 n=md(mdg+9) ; 建築要請
	  if n=6 or n=7 or n=8 or n=10 or n=11 : continue
	  ; 鍛冶屋、砦、警察、外交館、倉庫


	 if m2sc<pubsn(pn) { ; 現人材府数の配備を終えてない
	  mpn234_del m	; 順列からmNo.消去

	  if md(mdg+7)!5 : md(mdg+9)=-1 : continue ; 解体要請
	  if md(mdg+7)=0 {
	   if pubsn(pn)<pubsb and m2sbf=0 : md(mdg+9)=5 : m2sbf=1 ; 建設要請
	   continue
	  }

	  if stmf=0 {
	   hrs_pic 4 : if un=0 : stmf=1 ; un選択、魅力
	    if un>0 {
	     rh_eq un,4		; 魅力装備
	      mu(m*10)=un : ud(un*udb+13)=mdg ; 配備
	    }
	  }
 	  m2sc+
	  continue
	 }


 ; 現人材府数の配備を終えてる
 
; 満員では無い

	 if m2sf=0 { ; 満員では無い場合はサークル
	  mpn234_del m	; 順列からmNo.消去

	  repeat 1
	   if md(mdg+7)=3 or md(mdg+9)=3 : break ; 既にサークルがある
	   if md(mdg+7)>0 : md(mdg+9)=-1 : break ; 解体要請
	   md(mdg+9)=3 ; サークル建築要請
	  loop

	  if stmf=0 {
	   hrs_pic 2 : if un=0 : stmf=1 ; un選択、魔力
	    if un>0 {
	     rh_eq un,2		; 魔力装備
	      mu(m*10)=un : ud(un*udb+13)=mdg ; 配備
	    }
	  }
	  break
	 }


 ; 満員の場合
 
	 if pubsn(pn)>=pubsb { ; 人材府の数が最大
	  n=0 : f=0
	  repeat 25,1 : m2=cnt : mdg=m2*mdb
	   if map(m2)=0 or mpl(cnt)!pn : continue
	   if md(mdg+7)!5 : continue
	   if md(mdg+9)=-1 : f=1 : break ; 既に解体要請がある

	   if n=0 : n=m2 : continue
	   if md(n*mdb+3)>md(m2*mdb+3) : n=m2 ; 再弱国
	  loop

	  if f=0 : if md(m*mdb+3)>md(m2*mdb+3) : md(m2*mdb+9)=-1 : break ; 解体要請
	 }


	 if md(mdg+7)!5 : md(mdg+9)=-1 : break ; 解体要請
	 if md(mdg+7)=0 {
	  if pubsn(pn)<pubsb : if m2sbf=0 : md(mdg+9)=5 : m2sbf=1 ; 建設要請
	  mpn234_del m	; 順列からmNo.消去
	 }

	loop

	return

 
 
magic2_set ; 第二魔術地
 アイテム発見の鍛冶屋の第二候補地、魔術を伸ばすようにします。
 第二候補地 1つで良いため、マナ地よりは単純です。

#deffunc magic2_set ; 第二魔術地

	repeat 25 : m=mpn2(cnt) ; 人材地の選定
	 if m=0 : continue
	 mdg=m*mdb

	 n=md(mdg+7) ; 建築物
	  if n=1 or n=3 or n=5 or n=6 or n=7 or n=8 or n=10 or n=11 : continue
	  ; 城、サークル、人材府、鍛冶屋、砦、警察、外交館、倉庫
	 n=md(mdg+9) ; 建築要請
	  if n=3 or n=5 or n=6 or n=7 or n=8 or n=10 or n=11 : continue
	  ; サークル、人材府、鍛冶屋、砦、警察、外交館、倉庫
	loop
	if m=0 : return ; 用地無し

	mpn234_del m ; 順列からmNo.消去


; 人材配置
	if stmf=0 {
	 hrs_pic 3 : if un=0 : stmf=1 ; un選択、知力
	  if un>0 {
	   rh_eq un,3		; 知力装備
	    mu(m*10)=un : ud(un*udb+13)=mdg ; 配備
	  }
	}

 ; 建築要請
	n=md(mdg+7) ; 建築物
	 if n=0 : md(mdg+9)=2	; 塔
	 if n!2 : md(mdg+9)=-1	; 解体要請

	return

 
 
market_set ; 市場
 人口を伸ばす場所を 1つ選びます。

#deffunc market_set ; 市場

	m=0
	repeat 25,1
	 if map(cnt)=0 or mpl(cnt)!pn : continue
	 n=md(cnt*mdb+7)
	 if n=1 or n=2 or n=3 or n=5 or n=6 or n=7 or n=8 or n=10 or n=11 : continue
	 ; 城、塔、サークル、人材府、鍛冶、砦、警察、外交館、倉庫
	 if m=0 : m=cnt : continue
	 if md(cnt*mdb+1)>md(m*mdb+1) : m=cnt ; 一番人口が多い
	loop
	if m=0 : return ; 用地無し

	mpn234_del m	; 順列からmNo.消去

 ; 人材配置
	if stmf=0 {
	 hrs_pic 4 : if un=0 : stmf=1 ; un選択、魅力
	 if m>0 {
	  rh_eq un,4		; 魅力装備
	   mu(m*10)=un : ud(un*udb+13)=mdg ; 配備
	 }
	}

	n=md(mdg+7) ; 建築物
	 if n=0 : md(mdg+9)=4	; 市場
	 if n!4 : md(mdg+9)=-1	; 解体要請

	return

 
 
build_syo ; 建設処理
 以上の建設要請を元に建設を行います。

#deffunc bds int bdsn ; 建築処理

	if bdsn=-1 : bdsn2=12 : else : bdsn2=bdsn

	if bul_mp(bdsn2)>pmp(pn) : return ; マナが足りない

	repeat 25,1 : m=cnt
	 if map(m)=0 or mpl(m)!pn : continue
	 mdg=m*mdb
	  if md(mdg+9)!bdsn : continue
	 if bul_mp(bdsn2)>pmp(pn) : break		; マナが足りない

	 pmp(pn)-=bul_mp(bdsn2) : md(mdg+9)=0	; マナ消費、要請リセット
	 if bdsn=12 : md(mdg+7)=0 : continue	; 解体
	 md(mdg+7)=bdsn							; 建築
	loop

	return


#deffunc build_syo ; 建設処理

	if bul_mp(12)>pmp(pn) : return ; マナが足りない
	 bds -1	; 解体

	if bul_mp(10)>pmp(pn) : return ; マナが足りない
	 bds 10	; 外交館

	if bul_mp(5)>pmp(pn)  : return ; マナが足りない
	 bds 5	; 人材府

	if bul_mp(8)>pmp(pn)  : return ; マナが足りない
	 bds 8	; 警察署

	if bul_mp(7)>pmp(pn)  : return ; マナが足りない
	 bds 7	; 砦

	if bul_mp(6)>pmp(pn)  : return ; マナが足りない
	 bds 6	; 鍛冶屋

	if bul_mp(3)>pmp(pn)  : return ; マナが足りない
	 bds 3	; サークル

	if bul_mp(2)>pmp(pn)  : return ; マナが足りない
	 bds 2	; 塔

	if bul_mp(4)>pmp(pn)  : return ; マナが足りない
	 bds 4	; 市場
	
	if bul_mp(9)>pmp(pn)  : return ; マナが足りない
	 bds 9	; 寺院

	if bul_mp(11)>pmp(pn)  : return ; マナが足りない
	 bds 11	; 倉庫

	return

 
 
 各属領の領主配備をします。

	 repeat 25,1 : m=cnt ; 領主配備
	  if map(m)=0 or mpl(m)!pn : continue
	  if mu(m*10)>0 : continue ; 配備してる

	  hrs_pic 5		; un選択
	  rh_eq un,4	; 装備
	  mu(m*10)=un : ud(un*udb+13)=m*10 ; 配備
	 loop

 
 
government_set 0 ; 政府
 最後に人員が残ってるようなら政府に配属します。
 
 
 
 以上説明するだけで嫌になりますけど参考までにしました。
 まだ倉庫のプログラムも残ってるし終わってません。

 これを 3ヶ月思考錯誤しながら毎日ジリジリと進めていた訳です。
 いやほんとに大変だよコレ。
 
 
 8月の夏休み販売を計画してたけど、終わりそうにないなあ。
 
 

コメントを残す

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