📄 testbot.java
字号:
/* * MegaMek - * Copyright (C) 2000,2001,2002,2003,2004,2005 Ben Mazur (bmazur@sev.org) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. */package megamek.client.bot;import megamek.common.AmmoType;import megamek.common.Compute;import megamek.common.Coords;import megamek.common.Entity;import megamek.common.EquipmentType;import megamek.common.IAimingModes;import megamek.common.IEntityMovementType;import megamek.common.IHex;import megamek.common.Infantry;import megamek.common.Mech;import megamek.common.Minefield;import megamek.common.MiscType;import megamek.common.Mounted;import megamek.common.MovePath;import megamek.common.Protomech;import megamek.common.Terrains;import megamek.common.ToHitData;import megamek.common.WeaponType;import megamek.common.actions.ChargeAttackAction;import megamek.common.actions.DfaAttackAction;import megamek.common.actions.TorsoTwistAction;import megamek.common.actions.WeaponAttackAction;import megamek.common.event.GamePlayerChatEvent;import java.util.ArrayList;import java.util.Arrays;import java.util.Enumeration;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.TreeMap;import java.util.Vector;public class TestBot extends BotClient { public LinkedList unit_values = new LinkedList(); public LinkedList enemy_values = new LinkedList(); public CEntity.Table centities = new CEntity.Table(this); protected ChatProcessor chatp = new ChatProcessor(); public int ignore = 10; boolean debug = false; int enemies_moved = 0; GALance old_moves = null; int my_mechs_moved = 0; public TestBot(String name, String host, int port) { super(name, host, port); ignore = config.getIgnoreLevel(); debug = config.isDebug(); } public void initialize() { //removed } public PhysicalOption calculatePhysicalTurn() { return PhysicalCalculator.calculatePhysicalTurn(this); } public MovePath calculateMoveTurn() { long enter = System.currentTimeMillis(); int initiative = 0; MoveOption min = null; System.out.println("beginning movement calculations..."); //first check and that someone else has moved so we don't replan Object[] enemy_array = this.getEnemyEntities().toArray(); for (int j = 0; j < enemy_array.length; j++) { if (!((Entity) enemy_array[j]).isSelectableThisTurn()) { initiative++; } } // if nobody's moved and we have a valid move waiting, use that if (initiative == enemies_moved && old_moves != null) { min = this.old_moves.getResult(); if (min == null || !min.isMoveLegal() || (min.isPhysical && centities.get(min.getPhysicalTargetId()).isPhysicalTarget)) { this.old_moves = null; System.out.println("recalculating moves since the old move was invalid"); return calculateMoveTurn(); } } else { enemies_moved = initiative; ArrayList possible = new ArrayList(); Enumeration e = game.getEntities(); while (e.hasMoreElements()) { Entity entity = (Entity) e.nextElement(); // ignore loaded and off-board units if (entity.getPosition() == null || entity.isOffBoard()) { continue; } CEntity cen = centities.get(entity); cen.refresh(); firstPass(cen); } Iterator i = this.getEntitiesOwned().iterator(); boolean short_circuit = false; while (i.hasNext() && !short_circuit) { Entity entity = (Entity) i.next(); // ignore loaded units // (not really necessary unless bot manages to load units) if (entity.getPosition() == null) { continue; } // if we can't move this entity right now, ignore it if (!game.getTurn().isValidEntity(entity, game)) { continue; } CEntity cen = centities.get(entity); System.out.println("Contemplating movement of " + entity.getShortName() + " " + entity.getId()); MoveOption[] result = calculateMove(entity); if (game.getOptions().booleanOption("skip_ineligable_movement") && cen.getEntity().isImmobile()) { cen.moved = true; } else if (!cen.moved) { if (result.length < 6) { min = result.length > 0 ? (MoveOption) result[0] : null; short_circuit = true; } possible.add(result); } } //should ignore mechs that are not engaged //and only do the below when there are 2 or mechs left to move if (!short_circuit) { if (this.getEntitiesOwned().size() > 1) { GALance lance = new GALance(this, possible, 50, 80); lance.evolve(); min = lance.getResult(); this.old_moves = lance; } else if ( ((MoveOption[]) possible.get(0)) != null && ((MoveOption[]) possible.get(0)).length > 0) { min = ((MoveOption[]) possible.get(0))[0]; } } } if (min == null) { min = new MoveOption(game, centities.get(getFirstEntityNum())); } for (int d = 0; d < enemy_array.length; d++) { Entity en = (Entity) enemy_array[d]; // ignore loaded units if (en.getPosition() == null) { continue; } CEntity enemy = centities.get(en); int enemy_hit_arc = CEntity.getThreatHitArc(enemy.current.getFinalCoords(), enemy.current.getFinalFacing(), min.getFinalCoords()); MoveOption.DamageInfo di = (MoveOption.DamageInfo) min.damageInfos.get(enemy); if (di != null) { enemy.expected_damage[enemy_hit_arc] += di.min_damage; } if (enemy.expected_damage[enemy_hit_arc] > 0) { enemy.hasTakenDamage = true; } } if (min.isPhysical) { centities.get(min.getPhysicalTargetId()).isPhysicalTarget = true; } System.out.println(min); min.getCEntity().current = min; min.getCEntity().last = min; this.my_mechs_moved++; min.getCEntity().moved = true; long exit = System.currentTimeMillis(); System.out.println("move turn took " + (exit - enter) + " ms"); // If this unit has a jammed RAC, and it has only walked, // add an unjam action if (min != null) { if (min.getLastStep() != null) { if (min.getCEntity().entity.canUnjamRAC()) { if ((min.getLastStep().getMovementType() == IEntityMovementType.MOVE_WALK) || (min.getLastStep().getMovementType() == IEntityMovementType.MOVE_VTOL_WALK) || (min.getLastStep().getMovementType() == IEntityMovementType.MOVE_NONE)) { // Cycle through all available weapons, only unjam if the jam(med) // RACs count for a significant portion of possible damage int rac_damage = 0; int other_damage = 0; int clearance_range = 0; for (Mounted equip :min.getCEntity().entity.getWeaponList()) { WeaponType test_weapon = new WeaponType(); test_weapon = (WeaponType) equip.getType(); if ((test_weapon.getAmmoType() == AmmoType.T_AC_ROTARY) && (equip.isJammed() == true)) { rac_damage = rac_damage + 4 * (test_weapon.getDamage()); } else { if (equip.canFire()) { other_damage += test_weapon.getDamage(); if (test_weapon.getMediumRange() > clearance_range) { clearance_range = test_weapon.getMediumRange(); } } } } // Even if the jammed RAC doesn't make up a significant portion // of the units damage, its still better to have it functional // If nothing is "close" then unjam anyways int check_range = 100; for (Enumeration unit_selection = game.getEntities(); unit_selection.hasMoreElements();) { Entity enemy = (Entity) unit_selection.nextElement(); if ((min.getCEntity().entity.getPosition() != null) && (enemy.getPosition() != null) && (enemy.isEnemyOf(min.getCEntity().entity))) { if (enemy.isVisibleToEnemy()) { if (min.getCEntity().entity.getPosition().distance (enemy.getPosition()) < check_range) { check_range = min.getCEntity().entity.getPosition(). distance(enemy.getPosition()); } } } } if ((rac_damage >= other_damage) || (check_range < clearance_range)) { min.addStep(MovePath.STEP_UNJAM_RAC); } } } } } return min; } public MoveOption[] calculateMove(Entity entity) { ArrayList enemy_array = new ArrayList(game.getValidTargets(entity)); ArrayList<Entity> entities = new ArrayList<Entity>(game.getEntitiesVector()); CEntity self = centities.get(entity); MoveOption[] move_array;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -