Untitled

 avatar
unknown
python
25 days ago
3.0 kB
4
Indexable
import random
from functools import cache

def state_to_tuple_state(flipped_array, current_roll):
	return tuple(flipped_array + [current_roll])

def tuple_state_to_state(tuple_state):
	return list(tuple_state[:-1]), tuple_state[-1]

@cache
def get_all_possible_turn_downs(current_roll, chosen, cur_sum):
	rtn = []
	first = 1 if len(chosen) == 0 else chosen[-1] + 1
	chosen = set(chosen)
	for i in range(first, 10):
		if i in chosen:
			continue
		chosen.add(i)
		if cur_sum + i < current_roll:
			rtn += get_all_possible_turn_downs(current_roll, tuple(chosen), cur_sum + i)
		elif cur_sum + i == current_roll:
			rtn.append(list(chosen))
		else:
			pass
		chosen.discard(i)
	return rtn

def get_all_possible_turn_downs_with_state(flipped_array, current_roll):
	for flips in get_all_possible_turn_downs(current_roll, tuple(), 0):
		if all(flipped_array[flip - 1] == 1 for flip in flips):
			yield flips

def score(flipped_array):
	return sum(i + 1 for i, is_flipped in enumerate(flipped_array) if is_flipped)

@cache
def get_all_possible_ways_to_roll(target):
	count = 0
	for d1 in range(1, 7):
		for d2 in range(1, 7):
			if d1 + d2 == target:
				count += 1
	return count

@cache
def num_to_probability(num):
	return get_all_possible_ways_to_roll(num) / 36.0

def get_new_flipped_array(flipped_array, flips):
	return list(0 if (flipped_array[i] == 0) or i + 1 in flips else 1 for i in range(9))

@cache
def get_ev(tuple_state):
	flipped_array, current_roll = tuple_state_to_state(tuple_state)
	max_ev = -sum(i + 1 for i, is_flipped in enumerate(flipped_array) if is_flipped)
	max_ev_flips = []
	for flips in get_all_possible_turn_downs_with_state(flipped_array, current_roll):
		ev = 0
		new_flipped_array = get_new_flipped_array(flipped_array, flips)
		for roll in range(2, 13):
			ev += num_to_probability(roll) * get_ev(state_to_tuple_state(new_flipped_array, roll))[0]
		if ev > max_ev:
			max_ev = ev
			max_ev_flips = tuple(flips)
	return max_ev, max_ev_flips

@cache
def get_random_ev(tuple_state):
	flipped_array, current_roll = tuple_state_to_state(tuple_state)
	max_ev = -sum(i + 1 for i, is_flipped in enumerate(flipped_array) if is_flipped)
	ev = 0
	c = 0
	for flips in get_all_possible_turn_downs_with_state(flipped_array, current_roll):
		c += 1
		new_flipped_array = get_new_flipped_array(flipped_array, flips)
		for roll in range(2, 13):
			ev += num_to_probability(roll) * get_random_ev(state_to_tuple_state(new_flipped_array, roll))[0]
	if c == 0:
		return max_ev, []
	return ev // c, []

def get_ev_with_just_state(board_state):
	ev = 0
	for roll in range(2, 13):
		ev += num_to_probability(roll) * get_ev(state_to_tuple_state(board_state, roll))[0]
	return ev

def get_ev_if_random(board_state):
	ev = 0
	for roll in range(2, 13):
		ev += num_to_probability(roll) * get_random_ev(state_to_tuple_state(board_state, roll))[0]
	return ev

if __name__ == '__main__':
	print("average score if you play optimal", get_ev_with_just_state([1] * 9))
	print("average score if you play random", get_ev_if_random([1] * 9))
Editor is loading...
Leave a Comment