diff --git a/trainer.py b/trainer.py new file mode 100644 index 0000000000000000000000000000000000000000..172f2b5946a50e07a0a802ed0b84d5b43d5f23c0 --- /dev/null +++ b/trainer.py @@ -0,0 +1,123 @@ +import referee.__main__ +from referee.player import PlayerWrapper +from referee.options import get_options +from referee.log import StarLog +import random +import os + +NUM_GENERATIONS = 99 + +MIN_WEIGHT = 0 +MID_WEIGHT = 5 +MAX_WEIGHT = 10 +weight_vals = [MIN_WEIGHT, MID_WEIGHT, MAX_WEIGHT] + +weights = [[w1, w2, w3, w4, w5, 0] for w1 in weight_vals for w2 in weight_vals +for w3 in weight_vals for w4 in weight_vals for w5 in weight_vals] +WEIGHT_ARR_SIZE = 81 + +options = get_options() + +# Create a star-log for controlling the format of output from within this +# program +out = StarLog(level=options.verbosity, star="*") +out.comment("all messages printed by the referee after this begin with a *") +out.comment("(any other lines of output must be from your Player classes).") +out.comment() + +def train(weight_array): + + winners = [] + + for i in range(int(len(weight_array)/3)): + + red_weight = random.choice(weight_array) + weight_array.remove(red_weight) + green_weight = random.choice(weight_array) + weight_array.remove(green_weight) + blue_weight = random.choice(weight_array) + weight_array.remove(blue_weight) + + try: + os.remove('./Snek/player/weights') + except: + pass + + with open('./Snek/player/weights','a+') as weight_file: + weight_file.write(str(red_weight)) + weight_file.write("\n") + weight_file.write(str(green_weight)) + weight_file.write("\n") + weight_file.write(str(blue_weight)) + + p_R = PlayerWrapper('red player', options.playerR_loc, options, out) + p_G = PlayerWrapper('green player', options.playerG_loc, options, out) + p_B = PlayerWrapper('blue player', options.playerB_loc, options, out) + + winner = referee.__main__.play([p_R, p_G, p_B], options, out) + if "red" in winner: + p_R.init("red") + red_weight[-1] = calc_fitness(p_R) + winners.append(red_weight) + + elif "green" in winner: + p_G.init("green") + green_weight[-1] = calc_fitness(p_G) + winners.append(green_weight) + + elif "blue" in winner: + p_B.init("blue") + blue_weight[-1] = calc_fitness(p_B) + winners.append(blue_weight) + + return winners + +def calc_fitness(pl): + return pl.player.noMoves + +def next_generation_mutation(weight_array, num_to_gen): + next_gen_arr = [] + for i in range(num_to_gen): + list1 = weight_array[random.randint(0, len(weight_array)-1)].copy() + + ind1 = random.randint(0,len(list1)-2) + ind2 = random.randint(0,len(list1)-2) + + mult1 = random.randint(80,120)/100 + mult2 = random.randint(80,120)/100 + + list1[ind1] *= mult1 + list1[ind2] *= mult2 + + next_gen_arr.append(list1) + + for weight in weight_array: + next_gen_arr.append(weight) + + return next_gen_arr + +def next_generation_combination(weight_array, num_to_gen): + next_gen_arr = [] + for i in range(num_to_gen): + list1 = weight_array[random.randint(0, len(weight_array)-1)].copy() + list2 = weight_array[random.randint(0, len(weight_array)-1)].copy() + list3 = weight_array[random.randint(0, len(weight_array)-1)].copy() + + A = list1[-1] + B = list2[-1] + C = list3[-1] + + for j in range(len(list1)-1): + list_new.append((A*list1[j] + B*list2[j] + C*list3[j])/(A+B+C)) + list_new.append(0) + + next_gen_arr.append(list_new) + + for weight in weight_array: + next_gen_arr.append(weight) + + return next_gen_arr + +for i in range(NUM_GENERATIONS): + weights = train(weights) + weights = next_generation_mutation(weights, WEIGHT_ARR_SIZE - len(weights)) \ No newline at end of file