Java tutorial
/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package fr.ritaly.dungeonmaster.champion.body; import java.util.ArrayList; import java.util.Collections; import java.util.EnumMap; import java.util.List; import java.util.Map; import java.util.Random; import org.apache.commons.lang.Validate; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import fr.ritaly.dungeonmaster.champion.Champion; import fr.ritaly.dungeonmaster.champion.body.BodyPart.Type; import fr.ritaly.dungeonmaster.item.Item; /** * A champion's body is made of 7 body parts: * <ul> * <li>the head</li> * <li>the neck</li> * <li>the torso</li> * <li>the legs</li> * <li>the feet</li> * <li>the weapon hand</li> * <li>the shield hand</li> * </ul> * * @author <a href="mailto:francois.ritaly@gmail.com">Francois RITALY</a> */ public class Body { private final Log log = LogFactory.getLog(Body.class); /** * The {@link Champion} this body belongs to. */ private final Champion champion; /** * The body parts stored by type. */ private final Map<BodyPart.Type, BodyPart> parts = new EnumMap<BodyPart.Type, BodyPart>(BodyPart.Type.class); private final Random random = new Random(); public Body(Champion champion) { Validate.notNull(champion, "The given champion is null"); this.champion = champion; register(new Head(this)); register(new Neck(this)); register(new Torso(this)); register(new Legs(this)); register(new Feet(this)); register(new WeaponHand(this)); register(new ShieldHand(this)); } private void register(BodyPart bodyPart) { Validate.notNull(bodyPart, "The given body part is null"); parts.put(bodyPart.getType(), bodyPart); } public Champion getChampion() { return champion; } /** * Returns the body part with given type. * * @param type * a instance of {@link Type} representing the type of the * requested body part. * @return an instance of {@link BodyPart}. Never returns null. */ public BodyPart getPart(BodyPart.Type type) { Validate.notNull(type, "The given body part type is null"); switch (type) { case FEET: return getFeet(); case HEAD: return getHead(); case LEGS: return getLegs(); case NECK: return getNeck(); case SHIELD_HAND: return getShieldHand(); case TORSO: return getTorso(); case WEAPON_HAND: return getWeaponHand(); default: throw new UnsupportedOperationException("Unexpected body part type " + type); } } public BodyPart getHead() { return parts.get(BodyPart.Type.HEAD); } public BodyPart getNeck() { return parts.get(BodyPart.Type.NECK); } public BodyPart getTorso() { return parts.get(BodyPart.Type.TORSO); } public BodyPart getLegs() { return parts.get(BodyPart.Type.TORSO); } public BodyPart getFeet() { return parts.get(BodyPart.Type.FEET); } public WeaponHand getWeaponHand() { return (WeaponHand) parts.get(BodyPart.Type.WEAPON_HAND); } public Hand getShieldHand() { return (Hand) parts.get(BodyPart.Type.SHIELD_HAND); } /** * Collects (and removes) all the items worn by this body's parts and * returns them. * * @return a list of items. Never returns null. */ public List<Item> removeAllItems() { final List<Item> items = new ArrayList<Item>(); for (BodyPart bodyPart : parts.values()) { if (bodyPart.hasItem()) { items.add(bodyPart.takeOff(true)); } } return items; } /** * Collects (but doesn't remove) all the items worn by this body's parts and * returns them. * * @return a list of items. Never returns null. */ public List<Item> getItems() { final List<Item> items = new ArrayList<Item>(); for (BodyPart bodyPart : parts.values()) { if (bodyPart.hasItem()) { items.add(bodyPart.getItem()); } } return items; } /** * Tells whether at least one part of this body is wounded. * * @return whether at least one part of this body is wounded. */ public boolean isWounded() { for (BodyPart bodyPart : parts.values()) { if (bodyPart.isWounded()) { return true; } } return false; } /** * Tries to wound this body and returns whether the operation succeeded. * * @return whether at least one body part was wounded. */ public boolean wound() { if (log.isDebugEnabled()) { log.debug("Wounding " + getChampion().getName() + "'s body ..."); } // TODO Strength of wounds ? Number of wounds ? final List<BodyPart> bodyParts = getNonWoundedParts(); if (!bodyParts.isEmpty()) { // Randomly wound one of the non-wounded body parts Collections.shuffle(bodyParts); boolean wounded = false; while (!bodyParts.isEmpty() && !wounded) { wounded = bodyParts.remove(0).wound(); } return wounded; } return false; } /** * Tries to heal this body and returns whether the operation succeeded. * * @return whether at least one body part was healed. */ public boolean heal() { if (log.isDebugEnabled()) { log.debug("Healing " + getChampion().getName() + "'s body ..."); } // TODO Strength of healing ? Number of healings ? final List<BodyPart> bodyParts = getWoundedParts(); if (!bodyParts.isEmpty()) { // Randomly heal one of the wounded body parts final BodyPart bodyPart = bodyParts.get(random.nextInt(bodyParts.size())); bodyPart.heal(); if (log.isDebugEnabled()) { log.debug("Healed " + getChampion().getName() + "'s " + bodyPart.getType()); } return true; } return false; } /** * Returns this body's wounded parts. * * @return a list of body parts. Never returns null. * @see #getNonWoundedParts() */ public List<BodyPart> getWoundedParts() { final List<BodyPart> result = new ArrayList<BodyPart>(7); for (BodyPart bodyPart : parts.values()) { if (bodyPart.isWounded()) { result.add(bodyPart); } } return result; } /** * Returns this body's non-wounded parts. * * @return a list of body parts. Never returns null. * @see #getWoundedParts() */ public List<BodyPart> getNonWoundedParts() { final List<BodyPart> result = new ArrayList<BodyPart>(7); for (BodyPart bodyPart : parts.values()) { if (!bodyPart.isWounded()) { result.add(bodyPart); } } return result; } /** * Returns the total weight for all the items carried by this body. * * @return a float representing a weight (in kilograms). */ public float getTotalWeight() { float weight = 0.0f; for (BodyPart bodyPart : parts.values()) { weight += bodyPart.getWeight(); } return weight; } }