//--------------------------------------------------------------------// // 戦略シミュレーション ver.0.1 // // 2002/04/07 作成 樋口和宏 // //--------------------------------------------------------------------// // クラス一覧 // interface Parameters パラメータインターフェイス // interface Words 使用単語インターフェイス // interface ControlPanel コントロールパネルインターフェイス // interface DivisionAction 部隊行動パラメータインターフェイス // interface DivisionStatus 部隊状態パラメータインターフェイス // interface Exchange 交換ボタンインターフェイス // class WCP メイン // class WCPPanel フィールド表示部分 // class WCPDataCore データ管理 // class Formation 部隊編成クラス // class Supply 部隊補給クラス // class FieldParts フィールド部品クラス // class Castle 城クラス // class Grid フィールドデータクラス // class Nation 国家クラス // class Division 部隊クラス // class Weapon 兵種クラス // class General 武将クラス // class drawDivision 部隊描画クラス // class StringList 文字列リストクラス // class ControlButton コントロールボタンクラス // class ImageData イメージクラス // class ClearFilter 指定した色を透明にするフィルタ // class halfClearFilter 半透明にするフィルタ //--------------------------------------------------------------------// import java.applet.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.lang.*; import java.util.*; import java.io.*; import java.net.URL; //--------------------------------------------------------------------// // パラメータインターフェイス interface Parameters{ static final int FIELDMAX=100; // フィールド部品種類数の上限 static final int GRIDMAX=100000; // フィールドデータの上限 static final int CASTLEMAX=100; // 城の数の上限 static final int NATIONMAX=50; // 国家数の上限 static final int WEAPONMAX=50; // 兵種数の上限 static final int GENERALMAX=1000; // 武将数の上限 static final int NATIONDIV=100; // 国家所属部隊数の上限 static final int DIVGENERAL=10; // 部隊所属将軍数の上限 static final int COORDMAX=1000; // 座標値の上限 static final int TURNMAX=10000; // ターン数の上限 static final int MAXNUMBER=10000; // 物資・兵力の上限 static final int MAXCLASS=1000; // 城のパラメータの上限 static final int MAXPARAMETER=100; // パラメータの上限 static final int MINPARAMETER=10; // パラメータの下限 static final int NONE=-1; // ボタン・パネル選択 static final int GAME=0; // ゲーム続行 static final int GAMEOVER=-1; // ゲームオーバー static final int GAMEWIN=1; // ゲーム勝利 static final int GRID=10; // 描画範囲内のマス目の数 static final int GHALF=5; static final int MARGINX=4; // マージン static final int MARGINY=2; static final int MOVING=10; // 移動コマ最大数 static final int COST=100; // 建設・募兵コスト static final int MOVEMAX=5; // 必要機動力の上限 static final int EFFECTMAX=10; // 地形効果の上限 static final int AMBUSHCOEF=2; // 奇襲攻撃の係数 static final double FRONTCOEF=1.0; // 正面攻撃の係数 static final double SIDECOEF=0.8; // 側面攻撃の係数 static final double BACKCOEF=0.5; // 背後からの攻撃の係数 static final double ESCAPE=0.1; // 兵士脱走率 static final double EAT=1.0/30.0; // 1ターンの兵糧消費量 static final int NEWSOLDIER=10; // 新兵の訓練度 static final int ROYALDIVISION=0; // 王の所属する部隊 static final int CURSOR=0; // カーソル部品 static final int SELECTEDAREA=1; // 選択範囲部品 } //--------------------------------------------------------------------// // 使用単語インターフェイス interface Words{ static final String NEXTPAGE="次ページ"; static final String YES="はい",NO="いいえ"; static final String SELECTPLAYERNATION="プレイヤーの国家を選んで下さい"; static final String TACTICS="の戦略",TURN="ターン"; static final String GAMEOVERMESSAGE="は滅亡しました"; static final String GAMECLEARMESSAGE="は天下を統一しました"; static final String MOVENEED="必要機動力:"; static final String EFFECT="地形効果:"; static final String FOODLABEL="兵糧:"; static final String MONEYLABEL="資金:"; static final String FOODPRODUCT="農業生産:"; static final String MONEYPRODUCT="商業生産:"; static final String CASTLECLASS="城郭規模:"; static final String KING="君主:"; static final String SOLNUMBER="兵数:"; static final String DIVNUMBER="部隊数:"; static final String GENERALNUMBER="武将数:"; static final String TRAIN="訓練度:"; static final String WEAPON="兵種:"; static final String MOVEP="機動力:"; static final String POSITION="位置:"; static final String GENERALLIST[]={"武将名 ","政略","知略","指揮" ,"武力","魅力"}; static final String DIVSTATUS[]={"待機","移動済","行動済"}; static final String ARMYNAME[]={"第","軍"}; static final String AMBUSHD="伏兵"; static final String NATIONNAME="国家名 "; static final String DIVNAME="部隊名 "; static final String WEAPONNAME="兵種 "; } //--------------------------------------------------------------------// // コントロールパネルインターフェイス interface ControlPanel{ static final int LOCALMAP=-1; // 画面モード static final int GLOBALMAP=0; static final int DIVISIONLIST=1; static final int NATIONLIST=2; static final int TURNENDBUTTON=3; static final String CNTPANELBUTTON[]={"全体マップ","部隊一覧","国家一覧" ,"ターン終了"}; } //--------------------------------------------------------------------// // 部隊行動パラメータインターフェイス interface DivisionAction{ static final int MOVE=0; // 状態スイッチ static final int ATTACK=1; static final int DIRECTION=2; static final int FORMATION=3; static final int TRAINING=4; static final int SUPPLY=5; static final int CONSTRUCT=6; static final int CONSTFOOD=7; static final int CONSTMONEY=8; static final int CONSTCASTLE=9; static final int OCCUPY=10; static final int AMBUSH=11; static final int INFOMATION=12; static final int ACTIONEND=13; static final int ACTIONDONE=14; static final int PLAYERTURN=15; static final int ENEMYTURN=16; static final int SELECT=17; static final int EXCHANGE=18; static final int NATIONSELECT=19; static final int TURNEND=20; static final String DIVBUTTON[]={"移動","攻撃","方向","編成","訓練" ,"補給","建設","農業","商業","城郭" ,"占領","伏兵","情報","終了","済"}; static final String SELECTMESSAGE[]={"移動先を指定して下さい","攻撃相手を指定して下さい" ,"方向を指定して下さい","編成相手を指定して下さい"}; static final String TURNENDCONFIRM="行動を終了しますか?"; } //--------------------------------------------------------------------// // 部隊状態パラメータインターフェイス interface DivisionStatus{ static final int WAIT=0; // 部隊の状態 static final int MOVED=1; static final int DONE=2; static final int NORTH=0; // 部隊の向いている方向 static final int EAST=1; static final int SOUTH=2; static final int WEST=3; } //--------------------------------------------------------------------// // 交換ボタンインターフェイス interface Exchange{ static final int DELTA[]={1000,100,10}; // 交換量 static final String DELTALABEL1[]={"1000 >","100 >","10 >"}; static final String DELTALABEL2[]={"< 1000","< 100","< 10"}; static final int LEFTRIGHT=0; // 交換方向 static final int RIGHTLEFT=1; static final String SOLDIERSUPPLY="募兵"; static final String DECIDE="決定",CANCEL="取消"; } //--------------------------------------------------------------------// // メイン public class WCP extends Applet{ WCPPanel wcppanel; private Image template=null; private MediaTracker mt=new MediaTracker(this); //--------------------------------------------------------------------// public void init(){ // データ読み込み String fname,iname,fontName,size; int imageSize=40,fontSize=12; int waitTime1=200,waitTime2=10,attackAction=10; URL base=getDocumentBase(); fname=getParameter("data"); if(fname==null) fname="sumple.dat"; iname=getParameter("image"); if(iname==null) iname="template.gif"; size=getParameter("imagesize"); if(size!=null) imageSize=Integer.parseInt(size); fontName=getParameter("fontname"); if(fontName==null) fontName="Monospaced"; size=getParameter("fontsize"); if(size!=null) fontSize=Integer.parseInt(size); setLayout(new BorderLayout()); getTemplateImage(iname); try{ mt.waitForAll(); wcppanel=new WCPPanel(base,fname,template,imageSize ,fontName,fontSize,Color.black,Color.white); wcppanel.setRunParameter(waitTime1,waitTime2,attackAction); add("Center",wcppanel); } catch(InterruptedException e){ } } //--------------------------------------------------------------------// public void destroy(){ remove(wcppanel); } //--------------------------------------------------------------------// void getTemplateImage(String iname){ // テンプレートイメージ読み込み URL ibase=getClass().getResource(iname); template=getToolkit().getImage(ibase); mt.addImage(template,0); } } //--------------------------------------------------------------------// // フィールド表示部分 class WCPPanel extends Panel implements Runnable,MouseListener,MouseMotionListener,KeyListener ,Parameters,Words,ControlPanel,DivisionAction,DivisionStatus ,Exchange{ WCPDataCore dc; private Thread viewThread=null; private String errorMessage; // エラーメッセージ int fx,fy; // 地図表示サイズ・位置 int sy; // 文字表示高さ private Image bgImage; // ダブルバッファリング用イメージ private Graphics bg; int mapPoint=NONE; // 地図上の位置 int indexViewRange; // 1ページ当りのリスト行数 int divisionPage=0,nationPage=0; // リストページ数 int currentPage=1; // 現在のリストページ int currentIndex=0; // 現在のリスト位置 int mousex=0,mousey=0; // マウス位置 int mapmode=LOCALMAP; // 画面モード int status=NATIONSELECT; // 状態スイッチ int waitTime1=200; // 移動時表示待ち時間 int waitTime2=10; // 攻撃時表示待ち時間 int attackAction=10; // 攻撃行動グラフィック表示回数 Color backColor,textColor; // 背景色・文字色 int turn=0; // ターン数 String GameOverMessage,GameClearMessage; private Font font; // 文字フォント private FontMetrics fm; private boolean running=false; ControlButton divCntButton[]=new ControlButton[DIVBUTTON.length]; // ボタン ControlButton cntPnlButton[]=new ControlButton[CNTPANELBUTTON.length]; ControlButton exchangeButton[]=new ControlButton[6*DELTA.length]; ControlButton yes,no,soldierSupply,decide,cancel,nextPage; WCPPanel(URL base,String name,Image image,int imageSize ,String fontName,int fontSize,Color backColor,Color textColor){ font=new Font(fontName,Font.PLAIN,fontSize); this.backColor=backColor; this.textColor=textColor; getData(base,name,image,imageSize); setBackground(backColor); addMouseListener(this); addMouseMotionListener(this); addKeyListener(this); dc.setViewPoint(0); } //--------------------------------------------------------------------// void getData(URL base,String name,Image image,int imageSize){ // データ読み込み InputStream is=null; errorMessage=null; try{ is=new URL(base,name).openStream(); dc=new WCPDataCore(is,image,imageSize,backColor,textColor); } catch(Exception e){ errorMessage=e.toString(); } try{ if(is!=null) is.close(); } catch(Exception e){ } } //--------------------------------------------------------------------// void setRunParameter(int waitTime1,int waitTime2,int attackAction){ // アニメーションパラメータの設定 this.waitTime1=waitTime1; this.waitTime2=waitTime2; this.attackAction=attackAction; } //--------------------------------------------------------------------// void start(){ if(viewThread==null){ viewThread=new Thread(this); viewThread.start(); } } //--------------------------------------------------------------------// public void run(){ if(running) return; running=true; switch(status){ default: break; case MOVE: moveRun(); status=PLAYERTURN; break; case ATTACK: attackRun(); status=PLAYERTURN; break; case TRAINING: trainingRun(); status=PLAYERTURN; break; case ENEMYTURN: enemyTurnRun(); status=PLAYERTURN; break; } stop(); running=false; } //--------------------------------------------------------------------// void moveRun(){ // 移動行動 int i; if(dc.currentDivision!=NONE){ for(i=dc.moving-1;i>=0;i--){ dc.moveDraw(i); repaint(); try{ viewThread.sleep(waitTime1); } catch(InterruptedException e){ } } dc.setDivViewPoint(dc.currentNation,dc.currentDivision); dc.moveDone(); repaint(); } } //--------------------------------------------------------------------// void attackRun(){ // 攻撃行動 int i; if(dc.currentDivision!=NONE){ for(i=0;i=dc.nation[dc.currentNation].divisionNumber) EndOfDivision=true; } } dc.nextNation(); if(dc.currentNation==0) nextTurn(); if(dc.currentNation==dc.playerNation) EnemyTurn=false; } if(dc.game==GAME){ dc.setCurrentDivision(dc.playerNation,NONE); dc.setDivViewPoint(dc.playerNation,0); } repaint(); } //--------------------------------------------------------------------// void stop(){ viewThread=null; } //--------------------------------------------------------------------// public void mouseClicked(MouseEvent e){ } //--------------------------------------------------------------------// public void mousePressed(MouseEvent e){ int newpt; if(running) return; mousex=e.getX(); mousey=e.getY(); if(status==NATIONSELECT){ actionNationSelect(); } else if(status==EXCHANGE){ actionDivisionExchange(); } else if(status==SUPPLY){ actionSupply(); } else if(status==CONSTRUCT){ actionConstruct(); } else if(status==INFOMATION){ actionInfomation(); } else if(status==TURNEND){ actionTurnEnd(); } else{ switch(mapmode){ case LOCALMAP: newpt=dc.getMapPointLocal(mousex,mousey); if(newpt!=NONE){ mapPoint=newpt; switch(status){ case PLAYERTURN: actionPlayerTurn(); break; case MOVE: actionMove(); break; case ATTACK: actionAttack(); break; case DIRECTION: actionDirection(); break; case FORMATION: actionFormation(); break; } } else{ if(cntPnlButton[GLOBALMAP].press(mousex,mousey)){ mapmode=GLOBALMAP; cntPnlButton[GLOBALMAP].Release(); } else if(cntPnlButton[DIVISIONLIST].press(mousex,mousey)){ mapmode=DIVISIONLIST; divisionPage=(dc.nation[dc.playerNation].divisionNumber-1) /indexViewRange+1; currentPage=1; cntPnlButton[DIVISIONLIST].Release(); } else if(cntPnlButton[NATIONLIST].press(mousex,mousey)){ mapmode=NATIONLIST; nationPage=(dc.nationNumber-1)/indexViewRange+1; currentPage=1; cntPnlButton[NATIONLIST].Release(); } else if(cntPnlButton[TURNENDBUTTON].press(mousex,mousey)){ status=TURNEND; cntPnlButton[TURNENDBUTTON].Release(); } } break; case GLOBALMAP: actionGlobalMap(); break; case DIVISIONLIST: actionDivisionList(); break; case NATIONLIST: actionNationList(); break; } } repaint(); e.consume(); } //--------------------------------------------------------------------// void actionNationSelect(){ // 国家選択画面での行動 int ofset=(currentPage-1)*indexViewRange; if(nextPage.press(mousex,mousey)){ currentPage=currentPage%nationPage+1; nextPage.Release(); } else if(currentIndex=dc.viewSize || mousey>=dc.viewSize) return; nati=dc.grid[mapPoint].nation; div=dc.grid[mapPoint].division; x0=dc.gridSize*(dc.nation[nati].pointX(div)-dc.viewx+GHALF); y0=dc.gridSize*(dc.nation[nati].pointY(div)-dc.viewy+GHALF); if(x0<(int)(0.6*dc.viewSize)){ cx=x0+dc.gridSize+MARGINX; } else{ cx=x0-fm.stringWidth(DIVBUTTON[0])-2*MARGINX; } if(nati==dc.playerNation){ if(y0<(int)(0.6*dc.viewSize)){ cy[0]=y0+2; for(i=1;i0;i--){ cy[i-1]=cy[i]-sy; } } divCntButton[MOVE]=new ControlButton(fm,DIVBUTTON[MOVE],cx,cy[0]); divCntButton[ATTACK]= new ControlButton(fm,DIVBUTTON[ATTACK],cx,cy[1]); divCntButton[DIRECTION]= new ControlButton(fm,DIVBUTTON[DIRECTION],cx,cy[2]); divCntButton[FORMATION]= new ControlButton(fm,DIVBUTTON[FORMATION],cx,cy[3]); divCntButton[TRAINING]= new ControlButton(fm,DIVBUTTON[TRAINING],cx,cy[4]); if(dc.gridNation(mapPoint)==dc.playerNation){ divCntButton[SUPPLY]= new ControlButton(fm,DIVBUTTON[SUPPLY],cx,cy[5]); divCntButton[CONSTRUCT]= new ControlButton(fm,DIVBUTTON[CONSTRUCT],cx,cy[6]); divCntButton[CONSTFOOD]= new ControlButton(fm,DIVBUTTON[CONSTFOOD],cx,cy[0]); divCntButton[CONSTMONEY]= new ControlButton(fm,DIVBUTTON[CONSTMONEY],cx,cy[1]); divCntButton[CONSTCASTLE]= new ControlButton(fm,DIVBUTTON[CONSTCASTLE],cx,cy[2]); iend+=2; } else if(dc.grid[mapPoint].castle){ divCntButton[OCCUPY]= new ControlButton(fm,DIVBUTTON[OCCUPY],cx,cy[5]); iend++; } else if(dc.canHide(mapPoint)){ divCntButton[AMBUSH]= new ControlButton(fm,DIVBUTTON[AMBUSH],cx,cy[5]); iend++; } divCntButton[INFOMATION]= new ControlButton(fm,DIVBUTTON[INFOMATION],cx,cy[iend]); divCntButton[ACTIONEND]= new ControlButton(fm,DIVBUTTON[ACTIONEND],cx,cy[iend+1]); divCntButton[ACTIONDONE]= new ControlButton(fm,DIVBUTTON[ACTIONDONE],cx,cy[iend+1]); } else{ divCntButton[INFOMATION]= new ControlButton(fm,DIVBUTTON[INFOMATION],cx,y0); } } //--------------------------------------------------------------------// void setControlPanel(FontMetrics fm){ // コントロールパネル設定 int x1,x2,x0,y0; x0=dc.viewSize+MARGINX; y0=fy-2*sy-MARGINY; x1=x0+fm.stringWidth(CNTPANELBUTTON[0])+MARGINX; x2=x1+fm.stringWidth(CNTPANELBUTTON[1])+MARGINX; cntPnlButton[GLOBALMAP]= new ControlButton(fm,CNTPANELBUTTON[GLOBALMAP],x0,y0); cntPnlButton[DIVISIONLIST]= new ControlButton(fm,CNTPANELBUTTON[DIVISIONLIST],x1,y0); cntPnlButton[NATIONLIST]= new ControlButton(fm,CNTPANELBUTTON[NATIONLIST],x2,y0); cntPnlButton[TURNENDBUTTON]= new ControlButton(fm,CNTPANELBUTTON[TURNENDBUTTON],x0,y0+sy); x1=Math.max(fm.stringWidth(YES),fm.stringWidth(NO))+MARGINX; x0=fx/4-x1/2; y0=(fy-sy)/2; yes=new ControlButton(fm,YES,x0,y0,x1,sy); no=new ControlButton(fm,NO,x0+fx/2,y0,x1,sy); x0=2*MARGINX+fm.stringWidth(SELECTPLAYERNATION); y0=fy-sy-MARGINY; nextPage=new ControlButton(fm,NEXTPAGE,x0,y0); } //--------------------------------------------------------------------// void setExchangePanel(FontMetrics fm){ // 交換ボタンパネル設定 int i,i2,j,j1,j2,sx,x0,y0; int ex[]=new int[2*DELTA.length]; int ex0[]=new int[2*DELTA.length]; x0=fx/2; y0=MARGINY+4*sy; soldierSupply=new ControlButton(fm,SOLDIERSUPPLY,x0,y0); sx=fm.stringWidth(DECIDE)+MARGINX; x0=fx/4-sx/2; y0=fy-sy-MARGINY; decide=new ControlButton(fm,DECIDE,x0,y0); cancel=new ControlButton(fm,CANCEL,x0+fx/2,y0); for(i=0;i=0;i--){ i2=i+DELTA.length; ex0[i]=ex0[i+1]-ex[i]-MARGINX; ex0[i2]=ex0[i2+1]-ex[i2]-MARGINX; } for(i=0;i=dc.viewSize || mousey>=dc.viewSize) return; x0=(mousex/dc.gridSize)*dc.gridSize; y0=(mousey/dc.gridSize)*dc.gridSize; g.drawImage(dc.img.partImage[CURSOR],x0,y0,this); } //--------------------------------------------------------------------// void drawCursorGlobal(Graphics g){ // 全体マップでのカーソルの描画 int x0,y0,cx,cy; if(mousex>=dc.viewSize || mousey>=dc.viewSize) return; cx=dc.gridSize2*GRID; cy=dc.gridSize2*GRID; x0=(mousex/dc.gridSize2)*dc.gridSize2; x0=Math.min(Math.max(x0,cx/2),dc.gridSize2*dc.nx-cx/2); y0=(mousey/dc.gridSize2)*dc.gridSize2; y0=Math.min(Math.max(y0,cy/2),dc.gridSize2*dc.ny-cy/2); x0-=cx/2; y0-=cy/2; g.setColor(textColor); g.drawRect(x0,y0,cx,cy); g.drawRect(x0+1,y0+1,cx-2,cy-2); } //--------------------------------------------------------------------// void drawCursorDivisionList(Graphics g){ // 部隊リストでのカーソルの描画 int x0=1,y0,ofset=(currentPage-1)*indexViewRange; int maxIndex=Math.min(dc.nation[dc.currentNation].divisionNumber-ofset ,indexViewRange); if(currentIndex=viewSize || y>=viewSize) return NONE; ix=Math.min(Math.max(x/gridSize+viewx-GHALF,0),nx-1); iy=Math.min(Math.max(y/gridSize+viewy-GHALF,0),ny-1); return nx*iy+ix; } //--------------------------------------------------------------------// int getMapPointGlobal(int x,int y){ // 全体マップでのフィールド位置の獲得 int ix=0,iy=0; if(x>=viewSize || y>=viewSize) return NONE; ix=Math.min(Math.max(x/gridSize2,0),nx-1); iy=Math.min(Math.max(y/gridSize2,0),ny-1); return nx*iy+ix; } //--------------------------------------------------------------------// int gridNation(int point){ // 領有している国家 if(grid[point].castle){ return castle[grid[point].field].nation; } else{ return NONE; } } //--------------------------------------------------------------------// boolean canHide(int point){ // 伏兵可能判定 int nati=grid[point].nation,div=grid[point].division; int x=point%nx,y=point/nx; return canHide(nati,div,point,x,y); } //--------------------------------------------------------------------// boolean canHide(int nati,int div){ // 伏兵可能判定 int x=nation[nati].pointX(div),y=nation[nati].pointY(div); int point=y*nx+x; return canHide(nati,div,point,x,y); } //--------------------------------------------------------------------// boolean canHide(int nati,int div,int point,int x,int y){ // 伏兵可能判定 int nation4[]=new int[4]; if(!grid[point].castle){ if(fp[grid[point].field].hide){ if(y>0) nation4[0]=grid[point-nx].nation; // 北 else nation4[0]=NONE; if(y0) nation4[2]=grid[point-1].nation; // 西 else nation4[2]=NONE; if(xMath.abs(dy)){ if(dx>0) direc=EAST; else direc=WEST; } else{ if(dy>0) direc=SOUTH; else direc=NORTH; } nation[currentNation].setDirection(currentDivision,direc); } //--------------------------------------------------------------------// void setCurrentDivision(int nation,int div){ // 行動中の国家の設定 currentNation=nation; currentDivision=div; } //--------------------------------------------------------------------// void setMoveDistance(int nati,int div){ // 部隊移動可能範囲の設定 clearMoveDistance(); FindDistance(nation[nati].pointX(div),nation[nati].pointY(div) ,nation[nati].division[div].move); } //--------------------------------------------------------------------// int setMoveDistance(int point){ // 部隊移動可能範囲の設定 int nati=grid[point].nation,div=grid[point].division; if(nati==currentNation && div!=NONE){ setMoveDistance(nati,div); } currentDivision=div; return nati; } //--------------------------------------------------------------------// void FindDistance(int x,int y,int dist){ // 移動可能範囲の計算 int xy=y*nx+x,dnew; grid[xy].setMoveDistance(Math.max(grid[xy].moveDistance,dist)); if(dist==0) return; if(y>0 && CheckMove(xy-nx,dist)){ // 北 dnew=dist-Mobility(xy-nx); FindDistance(x,y-1,dnew); } if(y0 && CheckMove(xy-1,dist)){ // 西 dnew=dist-Mobility(xy-1); FindDistance(x-1,y,dnew); } if(x=0){ if(grid[xy].division==NONE && dist>=Mobility(xy)){ if(grid[xy].moveDistance=0){ moveDivision(grid[point].x,grid[point].y,grid[point].moveDistance); } else{ currentDivision=NONE; } } //--------------------------------------------------------------------// void moveDivision(int x,int y,int dist){ // 部隊移動の計算 int xy=y*nx+x; boolean hide=true; if(grid[xy].castle || !fp[grid[xy].field].hide) hide=false; while(dist!=nation[currentNation].division[currentDivision].move){ movingPoint[moving]=xy; dist+=Mobility(xy); if(y>0 && grid[xy-nx].moveDistance==dist){ movingDirection[moving]=SOUTH; xy-=nx; y--; } else if(y0 && grid[xy-1].moveDistance==dist){ movingDirection[moving]=EAST; xy--; x--; } else if(x0 && CheckAttack(xy-nx,dist)){ // 北 FindAttack(x,y-1,dnew); } if(y0 && CheckAttack(xy-1,dist)){ // 西 FindAttack(x-1,y,dnew); } if(x=0){ if(grid[xy].nation!=currentNation){ if(dist>0 && grid[xy].attackDistance=0){ if(nati!=currentNation && div!=NONE){ setDirection(point); attackedNation=nati; attackedDivision=div; return; } } currentDivision=NONE; } //--------------------------------------------------------------------// void setAttackDivision(int point,int nati,int div){ // 部隊攻撃の設定 if(nati!=currentNation && div!=NONE){ setDirection(point); attackedNation=nati; attackedDivision=div; } } //--------------------------------------------------------------------// void attackDraw(int step){ // 部隊攻撃描画 battle=!battle; } //--------------------------------------------------------------------// void attackCalculate(){ // 部隊攻撃ダメージ計算 double directionCoefficient; int i,direc; int attack1,defense1,field1,damage1,direc1; int attack2,defense2,field2,damage2,direc2; attack1=nation[currentNation].division[currentDivision].attack; defense1=nation[currentNation].division[currentDivision].defense; field1=divisionFieldEffect(currentNation,currentDivision); direc1=nation[currentNation].division[currentDivision].direction; attack2=nation[attackedNation].division[attackedDivision].attack; defense2=nation[attackedNation].division[attackedDivision].defense; field2=divisionFieldEffect(attackedNation,attackedDivision); direc2=nation[attackedNation].division[attackedDivision].direction; if(nation[currentNation].isHide(currentDivision)){ // 伏兵 attack1*=AMBUSHCOEF; defense1*=AMBUSHCOEF; } direc=(direc1-direc2+4)%4; switch(direc){ default: // 側面攻撃 directionCoefficient=SIDECOEF; break; case 0: // 背後からの攻撃 directionCoefficient=BACKCOEF; break; case 2: // 正面攻撃 directionCoefficient=FRONTCOEF; break; } damage1=attack1/(int)(directionCoefficient*defense2*field2); damage2=(int)(directionCoefficient*(attack2/(defense1*field1))); nation[attackedNation].Damage(attackedDivision,damage1); if(nation[currentNation].division[currentDivision].weapon.counter){ nation[currentNation].Damage(currentDivision,damage2); } nation[currentNation].appear(currentDivision); deleteDivision(attackedNation,attackedDivision); deleteDivision(currentNation,currentDivision); battle=false; attackedDivision=NONE; } //--------------------------------------------------------------------// void clearAttackDistance(){ // 部隊攻撃可能範囲の消去 int i; for(i=0;i0 && CheckFormation(xy-nx)){ // 北 grid[xy-nx].setFormationPlace(); } if(y0 && CheckFormation(xy-1)){ // 西 grid[xy-1].setFormationPlace(); } if(x=0){ if(grid[xy].division==NONE){ return true; } else if(grid[xy].nation==currentNation && nation[currentNation].CheckFormation(currentDivision,grid[xy].division)){ return true; } } return false; } //--------------------------------------------------------------------// void setFormationDivision(int point){ // 編成部隊の設定 int nati=grid[point].nation,div=grid[point].division; if(grid[point].formation){ formDivision1=currentDivision; formDivision2=grid[point].division; } else{ currentDivision=NONE; } } //--------------------------------------------------------------------// void clearFormation(){ // 編成部隊選択の解除 int i; for(i=0;i0 && formation.soldierNumber2()>0){ nation[currentNation].resetDivision(formDivision1,formation.formDivision1); if(formDivision2==NONE){ formDivision2=nation[currentNation].divisionNumber; nation[currentNation].addDivision(formDivision2,formation.formDivision2); grid[point].setDivision(currentNation,formDivision2); } else{ nation[currentNation].resetDivision(formDivision2,formation.formDivision2); } currentDivision=formDivision2; actionDone(); currentDivision=formDivision1; actionDone(); } else if(formation.soldierNumber1()==0 && formation.generalNumber1()==0){ if(formDivision2!=NONE){ nation[currentNation].resetDivision(formDivision1,formation.formDivision1); nation[currentNation].resetDivision(formDivision2,formation.formDivision2); currentDivision=formDivision2; actionDone(); deleteDivision(currentNation,formDivision1); } } else if(formation.soldierNumber2()==0 && formation.generalNumber2()==0){ if(formDivision2!=NONE){ nation[currentNation].resetDivision(formDivision1,formation.formDivision1); nation[currentNation].resetDivision(formDivision2,formation.formDivision2); currentDivision=formDivision1; actionDone(); deleteDivision(currentNation,formDivision2); } } formationCancel(); } //--------------------------------------------------------------------// void formationCancel(){ // 部隊編成の取消 formation=null; formDivision1=NONE; formDivision2=NONE; } //--------------------------------------------------------------------// void setSupply(int point){ // 部隊補給の設定 if(grid[point].castle){ supply=new Supply(nation[currentNation].division[currentDivision] ,castle[grid[point].field]); } } //--------------------------------------------------------------------// void foodSupply(int direc,int food){ // 兵糧補給 if(supply!=null){ switch(direc){ case LEFTRIGHT: supply.foodDivisionToCastle(food); break; case RIGHTLEFT: supply.foodCastleToDivision(food); break; } } } //--------------------------------------------------------------------// void moneySupply(int direc,int money){ // 資金補給 if(supply!=null){ switch(direc){ case LEFTRIGHT: supply.moneyDivisionToCastle(money); break; case RIGHTLEFT: supply.moneyCastleToDivision(money); break; } } } //--------------------------------------------------------------------// void soldierSupply(int point){ // 募兵 if(supply!=null){ if(supply.soldierSupply()) supplySet(point); else supplyCancel(); } } //--------------------------------------------------------------------// void supplySet(int point){ // 部隊補給の決定 if(supply!=null){ nation[currentNation].resetDivision(currentDivision,supply.division); castle[grid[point].field]=new Castle(supply.castle); castle[grid[point].field].setNation(supply.castle.nation ,supply.castle.nationColor); actionDone(); supplyCancel(); } } //--------------------------------------------------------------------// void supplyCancel(){ // 部隊補給の取消 supply=null; } //--------------------------------------------------------------------// void constructFoodProduct(int point){ // 城の農業開発 if(castle[grid[point].field].canFoodConstruct() && nation[currentNation].useMoney(currentDivision,COST)){ castle[grid[point].field].constructFoodProduct (nation[currentNation].Construct(currentDivision)); actionDone(); } } //--------------------------------------------------------------------// void constructMoneyProduct(int point){ // 城の商業開発 if(castle[grid[point].field].canMoneyConstruct() && nation[currentNation].useMoney(currentDivision,COST)){ castle[grid[point].field].constructMoneyProduct (nation[currentNation].Construct(currentDivision)); actionDone(); } } //--------------------------------------------------------------------// void constructCastleClass(int point){ // 城の規模拡大 if(castle[grid[point].field].canCastleConstruct() && nation[currentNation].useMoney(currentDivision,COST)){ castle[grid[point].field].constructCastleClass (nation[currentNation].Construct(currentDivision)); actionDone(); } } //--------------------------------------------------------------------// boolean Training(){ // 部隊訓練 if(nation[currentNation].division[currentDivision].training evalPoint){ evalPoint=point; moveTarget=i; attackedNation=grid[j].nation; attackedDivision=grid[j].division; } } } } } } //--------------------------------------------------------------------// void ambushDivision(){ // 伏兵 if(canHide(currentNation,currentDivision)) nation[currentNation].ambush(currentDivision); } //--------------------------------------------------------------------// void allWait(){ // 全部隊待機状態 int i; for(i=0;i=DIVGENERAL || ndiv==div) && ndiv=0 && grid[ii].division!=currentDivision){ g.drawImage(img.partImage[SELECTEDAREA],x0,y0,this); } ii++; } jj++; } } //--------------------------------------------------------------------// void drawAttackDistance(Graphics g){ // 攻撃可能範囲の描画 int i,j,ii,jj,gxy,x0,y0; jj=viewy-GHALF; for(j=0;j=0 && grid[ii].division!=currentDivision){ g.drawImage(img.partImage[SELECTEDAREA],x0,y0,this); } ii++; } jj++; } } //--------------------------------------------------------------------// void drawFormationPlace(Graphics g){ // 編成可能位置の描画 int i,j,ii,jj,gxy,x0,y0; jj=viewy-GHALF; for(j=0;j0){ y0+=sy; nation[i].drawNationList(g,x0,y0); } } } //--------------------------------------------------------------------// void drawDivisionList(Graphics g,FontMetrics fm,int sy,int indexViewRange ,int currentPage){ // 部隊リストの描画 int i,x0=5,y0=0,ofset=(currentPage-1)*indexViewRange; int maxIndex=Math.min(nation[currentNation].divisionNumber ,ofset+indexViewRange); for(i=ofset;i0 && formDivision2.generalNumber0 && formDivision1.generalNumber0){ StringList list=new StringList(g,x0,y0); list.setColor(color); list.drawString(name); list.setColor(textColor); list.tabString(NATIONNAME); list.space(); list.drawStringNumber(SOLNUMBER,soldierNumber() ,NATIONDIV*MAXNUMBER); list.space(); list.drawStringNumber(DIVNUMBER,divisionNumber,NATIONDIV); list.space(); list.drawStringNumber(GENERALNUMBER,generalNumber(),NATIONDIV*DIVGENERAL); } } //--------------------------------------------------------------------// void drawDivisionList(Graphics g,FontMetrics fm,int div,int x0,int y0){ // 部隊リストの描画 g.setColor(color); g.drawString(name,x0,y0); g.setColor(textColor); x0+=fm.stringWidth(name)+MARGINX; division[div].drawDivisionList(g,x0,y0); } //--------------------------------------------------------------------// void drawParameter(Graphics g,FontMetrics fm,int div,int x0,int y0,int sy ,Color textColor){ // 部隊情報の表示 int sx=fm.stringWidth(name)+MARGINX; g.setColor(color); g.drawString(name,x0,y0); g.setColor(textColor); division[div].drawParameter(g,fm,x0,y0,sx,sy); } //--------------------------------------------------------------------// void drawParameter(Graphics g,FontMetrics fm,int div,int x0,int y0,int sy ,Color backColor,Color textColor){ // 部隊情報の表示 int i,sx=fm.stringWidth(name)+MARGINX,fx=2*MARGINX,fy; g.setColor(backColor); for(i=0;i=DIVGENERAL) return; general[generalNumber]=gen; generalNumber++; setParameter(); } //--------------------------------------------------------------------// void deleteGeneral(int del){ // 部隊所属将軍の削除 int i; generalNumber--; for(i=del;i=cost){ money-=cost; return true; } else{ return false; } } //--------------------------------------------------------------------// void Damage(int damage){ // 部隊の戦闘によるダメージ soldierNumber=Math.max(soldierNumber-damage,0); setDivisionParameter(); } //--------------------------------------------------------------------// void Training(){ // 部隊訓練 int dtraining=Math.max(250*(strength+command)/soldierNumber,1); training=Math.min(training+dtraining,MAXPARAMETER); setDivisionParameter(); } //--------------------------------------------------------------------// void eatFood(){ // 兵糧消費 food=Math.max((int)((double)food-EAT*soldierNumber),0); if(food==0){ soldierNumber=(int)((1.0-ESCAPE)*soldierNumber); } } //--------------------------------------------------------------------// int Construct(){ // 部隊建設能力 return politics/5; } //--------------------------------------------------------------------// int Bonus(){ // 物資調達ボーナス return politics+charisma/2; } //--------------------------------------------------------------------// int getSoldier(){ // 兵士補充能力 return politics+charisma; } //--------------------------------------------------------------------// void drawDivisionLocal(Graphics g,int gxy,int x0,int y0 ,Color color,Color textColor){ // 部隊の描画 drawDivision.draw(g,gxy,x0,y0,soldierNumber,direction,hide,color,textColor); } //--------------------------------------------------------------------// void drawDivisionGlobal(Graphics g,int gxy,int x0,int y0 ,Color color,Color textColor){ // 全体マップでの部隊の描画 g.setColor(color); g.fillRect(x0,y0,gxy,gxy); g.setColor(textColor); g.drawRect(x0,y0,gxy,gxy); } //--------------------------------------------------------------------// void drawDivisionList(Graphics g,int x0,int y0){ // 部隊リストの描画 StringList list=new StringList(g,x0,y0); list.drawString(drawName(name)); list.tabString(DIVNAME); list.space(); list.drawStringNumber(FOODLABEL,food,MAXNUMBER); list.space(); list.drawStringNumber(MONEYLABEL,money,MAXNUMBER); list.space(); list.drawStringNumber(SOLNUMBER,soldierNumber,MAXNUMBER); list.space(); list.drawStringNumber(TRAIN,training,MAXPARAMETER); list.space(); list.drawStrings(WEAPON,weapon.name,WEAPONNAME); list.space(); list.drawStringNumber(GENERALNUMBER,generalNumber,DIVGENERAL); list.space(); list.drawStringNumber(POSITION+" x =",x,COORDMAX); list.space(); list.drawStringNumber("y =",y,COORDMAX); list.space(); list.drawString(DIVSTATUS[status]); } //--------------------------------------------------------------------// void drawDivisionExchange(Graphics g,int x0,int y0,int sy){ // 部隊編成の描画 int i; StringList list=new StringList(g,x0,y0); list.drawString(drawName(name)); list.lineFeed(sy); list.drawStringNumber(FOODLABEL,food,MAXNUMBER); list.lineFeed(sy); list.drawStringNumber(MONEYLABEL,money,MAXNUMBER); list.lineFeed(sy); list.drawStringNumber(SOLNUMBER,soldierNumber,MAXNUMBER); list.lineFeed(sy); list.drawStringNumber(TRAIN,training,MAXPARAMETER); list.lineFeed(sy); list.drawStringNumber(GENERALNUMBER,generalNumber,DIVGENERAL); for(i=0;i