Python
En garde!
My warrior combines unpredictability with a keen eye for weakness in his opponent's stance. He's pretty confident he'll be able to dispose of aggressive foes but his trainer (me) may have failed to anticipate certain scenarios or, perhaps more worrying, may have misinterpreted the rules (bugs!!).
Anyway I'm new so hopefully this is an ok format for the code:
from random import choice, random
def cleverly_pick_move(me_allowed,op_allowed,opp_last_move=None) :
""" Behold the genius you're up against!
Pretty much everything else is just flavour text or match rules
so you'll probably only want to read this...
"""
heights = ['head','chest','feet']
rand_choice = lambda a,h : {'type':choice([t for t in a if a[t]]),
'height':choice(h)}
if opp_last_move is None or feeling_like_a_lucky_punk():
return rand_choice(me_allowed,heights)
if sum(1 for x in op_allowed if op_allowed[x]) == 3 :
for i in op_allowed:
if not op_allowed[i] :
weakness = i
break
return {'type':exploit_weakness(weakness,me_allowed),
'height':choice(heights)}
return rand_choice(me_allowed,heights)
def exploit_weakness(weakness,me_allowed) :
moves = ['attack','parry','lunge','block']
for i,move in enumerate(moves) :
if move == weakness :
if me_allowed[moves[(i+1) % 4]] :
return moves[(i+1) % 4]
break
if me_allowed[weakness] :
return weakness
return choice([x for x in me_allowed if me_allowed[x]])
def feeling_like_a_lucky_punk() :
return random() > 0.8
def main():
this_round = 1
opp_last_move = None
score = {'myself':0, 'the blaggard':0}
quips = ['blaggard', 'fool', 'scum', 'raggamuffin']
adverbs = ['deftly', 'skillfully', 'gracefully', 'clumsily']
me_allowed = {'attack':True,'block':True,'lunge':True,'parry':True}
op_allowed = {'attack':True,'block':True,'lunge':True,'parry':True}
while (this_round <= 50 and
all([points < 3 for points in score.values()])) :
if this_round == 1 :
move = cleverly_pick_move(me_allowed,op_allowed)
else:
move = cleverly_pick_move(me_allowed,op_allowed,
opp_last_move=opp_last_move)
print "Our hero %s %ss at the %s's %s" % (
choice(adverbs),
move['type'],
choice(quips),
move['height']
)
print "We await the %s's response..." % choice(quips)
print "Our hero's move: " + (move['type'][0]+move['height'][0]).upper()
opp_move = parse_move(raw_input("Opponent's move: "))
outcome,me_allowed,op_allowed = get_outcome(move,opp_move,me_allowed,
op_allowed)
if outcome == 'WIN' :
print "Our hero pulls off an excellent round!"
score['myself'] += 1
elif outcome == 'LOSE' :
print "Never before have we seen such blatant cheating!"
score['the blaggard'] += 1
else :
print "Our hero is clearly toying with his opponent as he allows \
a drawn round."
print ("""The score after round %d:\nOur hero:\t%d\nHis opponent:\t%d"""
% (this_round, score['myself'], score['the blaggard']))
opp_last_move = opp_move
this_round += 1
print "Match over, surely the victory is mine!"
print """Final score:\n
Our hero:\t%d\nOpponent:\t%d""" % (score['myself'],
score['the blaggard'])
if score['myself'] > score['the blaggard'] :
print "My victory was inevitable!"
elif score['myself'] == score['the blaggard'] :
print "An even match! Huzzar!"
else :
print ""
return
def reset_allowed(dictionary) :
return dict((x,True) for x in dictionary)
def get_outcome(mymove,opmove,me_allowed,op_allowed) :
result = ''
if not me_allowed[mymove['type']] :
print "Whoops, I forgot I couldn't do that..."
result = 'LOSE'
if not op_allowed[opmove['type']] :
print "Haha! What a clutz!"
result = 'WIN'
if mymove['height'] != opmove['height'] :
print "The combatants flail at each other with little effect!"
print "They'll have to try something else next round!"
result = 'DRAW'
if mymove['type'] == opmove['type'] :
if mymove['type'] in ['attack','lunge']:
print "The combatants' blades clash dramatically!"
else :
print "Both combatants take a moment to practice their \
defensive stance..."
result = 'DRAW'
if result :
me_allowed, op_allowed = (reset_allowed(me_allowed),
reset_allowed(op_allowed))
if mymove['height'] != opmove['height'] :
me_allowed[mymove['type']] = op_allowed[opmove['type']] = False
return (result, me_allowed,op_allowed)
else :
return compare_attacks(mymove,opmove,me_allowed,op_allowed)
def compare_attacks(mymove,opmove,me_allowed,op_allowed) :
"""
0 A > P 1
^ x v
3 B < L 2
"""
print "Our hero %ss, his opponent %ss!" % (mymove['type'],opmove['type'])
move_val = {'attack':0,'parry':1,'lunge':2,'block':3}
result_num = (move_val[opmove['type']] - move_val[mymove['type']]) % 4
results = ['DRAW','WIN','DRAW','LOSE']
me_allowed, op_allowed = (reset_allowed(me_allowed),
reset_allowed(op_allowed))
if result_num == 1 :
print "Our hero easily outwits his foe! *Huge cheers from crowd*"
return ('WIN',me_allowed,op_allowed)
elif result_num == 3 :
print "Our hero graciously allows his opponent a charity point.\
*A torrent of boos from the crowd*"
return ('LOSE',me_allowed,op_allowed)
else:
# Combatants drew and will have their moves restricted next round.
if mymove['type'] in ['attack','parry'] :
me_allowed['attack'] = me_allowed['lunge'] = False
me_allowed['parry'] = me_allowed['block'] = True
op_allowed['parry'] = op_allowed['block'] = False
op_allowed['attack'] = op_allowed['lunge'] = True
else :
me_allowed['parry'] = me_allowed['block'] = False
me_allowed['attack'] = me_allowed['lunge'] = True
op_allowed['attack'] = me_allowed['lunge'] = False
op_allowed['parry'] = op_allowed['block'] = True
return ('DRAW',me_allowed,op_allowed)
def parse_move(move_string) :
m_types = {'A':'attack','B':'block','L':'lunge','P':'parry'}
m_heights = {'C':'chest','H':'head','F':'feet'}
move_string = move_string.strip().upper()
if not move_string :
print "Couldn't understand your input: %s" % move_string
return parse_move(raw_input("Opponent's move: "))
if move_string[0] not in m_types :
move_string = move_string[::-1]
try :
move = {'type':m_types[move_string[0]],
'height':m_heights[move_string[1]]}
return move
except KeyError :
print "Couldn't understand your input: %s" % move_string
return parse_move(raw_input("Opponent's move: "))
if __name__ == '__main__' :
main()
1note: targetting the current winners algorithm to counter that player is in the nature of fencing, and this is king-of-the-hill, so such action is not only allowed, but also ENCOURAGED! - try to come up with some method of generating results, obfuscating your code, or some other way to "guard" yourself, and figure the best way to "attack" the other player's code! -- PLEASE KEEP ALL DISCUSSION CIVIL -- – NRGdallas – 2012-09-07T21:59:06.327
once defeated, if you want to offer insight into how you did things, why you did things a certain way, etc, in comments or by modifying your answer, feel free to. While your code is in line, however, please refrain from editing :) – NRGdallas – 2012-09-07T22:00:42.533
Is your example correct? It seems to mangle an input of LC into an action of LM. – Peter Taylor – 2012-09-08T08:33:39.093
What about randomness in the solution? Must the match be deterministic? If not, how will the judge select the seed, and how many games will be played between two programs, just one? The robocode competitions usually have 10, to limit the effects of blind chance. – vsz – 2012-09-08T09:03:32.250
this.hits=0;opponent.hits=Infinity;
:) – Anish Gupta – 2012-09-08T10:34:19.430@PeterTaylor updated example, originally it was top, middle, bottom, however I changed to head feet chest to avoid the bottom and block being same letters - as for randomness, the program must be able to run "out of the box" - as in no prompt for the "seed" should occur etc
as for blind chance, I will run a best of 5
I am also partially doing this as I don't know how to run scripts/programs in all the various languages, so I hope to use the results in this as a learning experience myself :) – NRGdallas – 2012-09-10T17:14:03.247
What happens if both choose the same action at the same height? – quasimodo – 2012-09-23T14:43:33.287
@Quasimodo tie, the round is ignored. – NRGdallas – 2012-09-25T20:11:03.150
is this roughly the algorithm? while rounds < 50 and myscore < 3 and yourscore < 3: choose my move, and output; input opponent's move; score my move against opponent's move, and output – Griffin – 2012-11-15T13:58:49.813
@Griffin Yes, that would be about right, so long as input and output follows basic rules – NRGdallas – 2012-11-15T16:16:04.203
3I don't really like how this is designed. I think you should come up with the code to run the match by running 2 submitted programs, relaying the moves and calculating the scores. The fencing programs should just print their moves to stdout and read the opponent's moves form stdin. – aditsu quit because SE is EVIL – 2013-03-05T17:42:31.920