250 likes | 340 Views
2012 程式設計比賽 Openfind 天使帝國 v2.0 ( 蓋亞的紋章 ). Preview. 比賽規則 (1/2). 由 Player(Blue) 的部隊跟 CPU(Red) 控制的部隊互攻 地圖大小 10x7 起始戰役 Player 經費 1000 元可自行購買兵種 採回合制 ( 每場最多 50 回合 ) ,由 Player 先攻 每場戰役結束 ( 一方全滅 or 50 回合到達 ) 每殺死 CPU 部隊,獲得 50% 死亡部隊價格當作 score
E N D
2012 程式設計比賽 Openfind 天使帝國 v2.0 (蓋亞的紋章)
比賽規則 (1/2) • 由Player(Blue)的部隊跟CPU(Red)控制的部隊互攻 • 地圖大小 10x7 • 起始戰役Player經費 1000 元可自行購買兵種 • 採回合制(每場最多50回合),由 Player 先攻 • 每場戰役結束(一方全滅 or 50回合到達) • 每殺死CPU部隊,獲得50% 死亡部隊價格當作score • 戰役結束,玩家每剩下一支部隊(不論血量),獲得50% 該存活部隊價格當作score
比賽規則 (2/2) • 每場戰役玩家會得到 1000元(基本消費) + 上一場戰役得到score+ 上一場戰役剩下的錢 • CPU 每場戰役會比上一場多 300元 • 總共10場戰役,10 場戰役每場 score累加,最高者得冠軍
戰士 • 生命值:500 • 攻擊:170 • 防禦:50 • 移動力:3 • 攻擊方式:近戰 • 特殊能力:被近身攻擊可反擊 • 價格:200
法師 • 生命值:240 • 攻擊:200 • 防禦:0 • 移動力:1 • 攻擊方式:遠程法術 • 施法距離:3 • 移動方式:步行 • 特殊能力:攻擊無視防禦 • 價格:400
屬性相剋 • 總共有風火水土四種屬性 • 土剋水 • 水剋火 • 火剋風 • 風剋土 • 相剋屬性(土屬性攻擊水屬性),可獲得200%攻擊效果 • 被剋屬性(水屬性攻擊土屬性),攻擊效果削弱50% • 不相干屬性互打,沒特別加成或是削弱
每回合輪到 Player • 每支部隊只能行動一次,行動完畢必須要等下回合 • CMD_MOVE: 移動,之後此部隊本回合行動結束 • CMD_MOVE_AND_ATTACK: 移動後施展攻擊,之後此部隊本回合行動結束 • CMD_END_TURN: Player 主動宣告此回合結束 • 移動 src => dest,其中 src 可以等於 dest (代表站在原地) • 每支部隊都行動過後,本回合自動結束換 CPU 部隊行動
移動規則 • 每步只能走上下左右四個方向 (不能走斜線) • 步行 – 移動距離(3)當作例子,可以走 0步(停在原地)、1步、2步、或是3步。只是每一步都必須有空地可以停留。(如右圖)
近戰攻擊規則 (A 攻擊 B) • B 必須為敵軍 • 每回合可施展移動後攻擊一次 • 殺傷力= (A.攻擊 – B.防禦)xAdj(屬性調整) • (1)殺傷力判斷為 A.攻擊-B.防禦 • (2)若屬性無相剋,Adj為 100% • (3)若屬性A剋B,Adj為 200% • (4)若屬性B剋A,Adj為 50% • (5)B存活且具備近戰反擊能力,將自動反擊A一次
遠程法術攻擊規則 (A 攻擊 B) • B 必須為敵軍 • 每回合可施展移動後攻擊一次 • 殺傷力= A.攻擊力(無視對方防禦)xAdj(屬性調整) • 若施法攻擊鄰近單位B,B未陣亡且具備反擊能力,將自動反擊A • 屬性相剋調整同上頁 (50%、100%、200%)
分數計算 & 戰役結束 • 戰役結束條件為 (1)一方全滅或(2)超過50回合 • 戰役中擊殺敵軍 B 可以得到 B.價格x50% 獎金 • 戰役結束後,PLAYER方殘存部隊得 A.價格x50%獎金 • 總獎金 + 本戰役剩下的錢可帶入下一場戰役,所以下一場戰役起始會有上述金額 + 1,000元 的經費 • 每場戰役打越好,下一場錢越多,富人越富 • 每場戰役打越差,下一場錢越少,窮人越窮 • 搞砸一場戰役,等於打入深淵
處罰條件 • 有任何錯誤 (buildArmy, move, moveAndAttack),直接判定該戰役得零分 • 超過 30 秒沒有移動,該戰役得零分 • 找到一個系統錯誤,可以拔 Mike 頭髮一根
Openfind 天使帝國 Programming Guide
User.dll • 主程式 scoring.exe 將呼叫 User.dll (dynamic) • User project 中包括 • User.dsw(VC++ compiler) • User.cpp -> 主要回傳 functions 都在此 • check.h -> 資料結構以及輔助 functions 都在此
Callback function (1/2) • void buildArmy(int team[21], int money) • Main system 每場戰役開始前會呼叫此 function • Users 把自己的起始部隊配置放在 team[21](位置如右圖),且花的錢不能超過 money
Callback function (2/2) • int playerMove(POINT pt[3]) • Main system 每回合不斷呼叫,直到使用者行動完畢回合結束 • Pt[0]: src, pt[1]: dest, pt[2]: target • CMD_MOVE: 從 pt[0] 走到 pt[1] • CMD_MOVE_AND_ATTACK: 從pt[0]走到pt[1]並攻擊pt[2] • CMD_END_TURN: 主動宣告回合結束
Data structure (#define and global) • #define WALL 0 • #define SPACE 1 • #define WARRIOR_WIND 2 • #define WARRIOR_FIRE 3 • #define WARRIOR_WATER 4 • #define WARRIOR_EARTH 5 • #define MAGICIAN_WIND 6 • #define MAGICIAN_FIRE 7 • #define MAGICIAN_WATER 8 • #define MAGICIAN_EARTH 9 • g_nTurn : The current turn.
Data structure (g_map) • struct MAP • { • int armyType; // can be 2 ~ 9 • int armySide; // 1 is Player, 2 is CPU • int live; // 這支部隊剩下多少生命值 • int alreadyMoved; // 0 is false, 1 is true • int id; // An unique id for each army (繪圖使用) • } g_map[MAP_X_SIZE][MAP_Y_SIZE]; • 地圖大小:MAP_X_SIZE * MAP_Y_SIZE • Global variable g_map:整張地圖上每個點的資訊
Data structure (g_army) • struct • { • int live; //生命值 • int attack; //攻擊力、法術攻擊量 • int defence; //防禦力 • int attackRange; //攻擊範圍 • int moveRange; //移動力 • int type; //風(0) 火(1) 水(2) 土(3) • int isFightBack; //是否可近戰反擊 (0) or (1) • int isSpell; //是否為法術攻擊 (0) or (1) • int price; // 部隊價格 • } g_army[TOTAL_ICON]; • 可用範圍:g_army[2]~g_army[9] • 僅當作 check functions 的參考,自行修改是沒用的
Utils • 自我檢查 PLAYER build army 是否合法 • // Function: intcheckBuildArmy(int player[21], int money) • // Input • // int player[21]: 對應到地圖左邊的三排位置, • // 每個位置放入兵種 2 ~ 9 或是 SPACE(代表空的) • // Return • // >=0: The content of player[21] is ok, return 剩下的金額 • // ERR_INVALID_TYPE: At least one of the position contains • invalid type • // ERR_EXCEED_COST: The total cost of player[21] exceeds the • maximum value (傳入的 money)
Utils • 取得 src 可以移動到那些 dest[] • //Function int getMove(POINT src, POINT dest[70], int userType) • // Input • // src: The original point of the army you want to move • // dest[70]: All the result of available move points will be stored in this array • // userType: should be PLAYER(1) or CPU(2) • // • // Return • // 0 ~ positive value: The count of total available moves. • // ERR_INPUT: The input userType is not PLAYER(1) or CPU(2) • // ERR_NOT_PLAYER: The army in the src does not belong to you • // ERR_ALREADY_MOVE: The army in the src has performed an move already.
Utils • 取得 src 可以法術攻擊那些 dest[] • // Function int getSpellAttack(POINT src, POINT dest[70], int userType) • // Input • // src: The original point of the army that you want to cast an offence spell • // dest[70]: All the result of available targets will be stored in this array • // userType: should be PLAYER(1) or CPU(2) • // • // Return • // 0 ~ positive value: The count of total available points of targets. • // ERR_INPUT: The input userType is not PLAYER(1) or CPU(2) • // ERR_NOT_PLAYER: The army in the src does not belong to you • // ERR_ALREADY_MOVE: The army in the src has performed move and attack already • // ERR_CANNOT_CAST: The army in the src does have the ability to case an offence spell
Utils • 自我檢查 src =>dest 是否正確 • // Function int checkMove(POINT src, POINT dest, int userType) • // To check move from src to dest is legal or not, but will not perform it. • // • // Input • // src: The original point that you want to move your army • // dest: The destination point that you want to move your army • // userType: Should be PLAYER(1) or CPU(2) • // • // Return • // SUCCESS: Your move is valid. • // ERR_INPUT: The input userType is not PLAYER(1) or CPU(2) • // ERR_NOT_PLAYER: The src does not belong to you • // ERR_ALREADY_MOVE: The src has performed move already. • // ERR_ILLEGAL_DEST: The dest is not empty or out of range
Utils • 自我檢查 src =>dest 然後攻擊 target 是否正確 • // Function intcheckMoveAndAttack(src,dest,target,userType) • // To preform move then attack. If you don't want to move, you can just input src==dest • // Once performing attacking, the army cannot be moved anymore. • // • // Input • // src: The original point of your army • // dest: The destination point of your army • // target: The target point that you want to attack • // userType: Should be PLAYER(1) or CPU(2) • // • // Return • // SUCCESS: Your move and attack is valid • // ERR_INPUT: The input userType is not PLAYER(1) or CPU(2) • // ERR_NOT_PLAYER: The src does not belong to you, or cannot perform attack • // ERR_ALREADY_MOVE: The src has performed move already • // ERR_ILLEGAL_DEST: The dest is not empty or out of range • // ERR_ILLEGAL_TARGET: The target cannot be attacked (not enemy or not reachable)