root/2d/iching.gd

extends Node2D

# Declare member variables here. Examples:
# var a = 2
# var b = "text"

# Called when the node enters the scene tree for the first time.

var hexagrams = Dictionary()

func init_hexagram(id, string, lines):
	hexagrams[id] = lines

func _ready():
	randomize()
	init_hexagram( 1, "䷀䷀䷀䷀䷀", [1,1,1,1,1,1])
	init_hexagram( 2, "䷁", [0,0,0,0,0,0])
	init_hexagram( 3, "䷂", [0,1,0,0,0,1])
	init_hexagram( 4, "䷃", [1,0,0,0,1,0])
	init_hexagram( 5, "䷄", [0,1,0,1,1,1])
	init_hexagram( 6, "䷅", [1,1,1,0,1,0])
	init_hexagram( 7, "䷆", [0,0,0,0,1,0])
	init_hexagram( 8, "䷇", [0,1,0,0,0,0])
	init_hexagram( 9, "䷈", [1,1,0,1,1,1])
	init_hexagram(10, "䷉", [1,1,1,0,1,1])
	init_hexagram(11, "䷊", [0,0,0,1,1,1])
	init_hexagram(12, "䷋", [1,1,1,0,0,0])
	init_hexagram(13, "䷌", [1,1,1,1,0,1])
	init_hexagram(14, "䷍", [1,0,1,1,1,1])
	init_hexagram(15, "䷎", [0,0,0,1,0,0])
	init_hexagram(16, "䷏", [0,0,1,0,0,0])
	
	init_hexagram(17, "䷐", [0,1,1,0,0,1])
	init_hexagram(18, "䷑", [1,0,0,1,1,0])
	init_hexagram(19, "䷒", [0,0,0,0,1,1])
	init_hexagram(20, "䷓", [1,1,0,0,0,0])
	init_hexagram(21, "䷔", [1,0,1,0,0,1])
	init_hexagram(22, "䷕", [1,0,0,1,0,1])
	init_hexagram(23, "䷖", [1,0,0,0,0,0])
	init_hexagram(24, "䷗", [0,0,0,0,0,1])
	init_hexagram(25, "䷘", [1,1,1,0,0,1])
	init_hexagram(26, "䷙", [1,0,0,1,1,1])
	init_hexagram(27, "䷚", [1,0,0,0,0,1])
	init_hexagram(28, "䷛", [0,1,1,1,1,0])
	init_hexagram(29, "䷜", [0,1,0,0,1,0])
	init_hexagram(30, "䷝", [1,0,1,1,0,1])
	init_hexagram(31, "䷞", [0,1,1,1,0,0])
	init_hexagram(32, "䷟", [0,0,1,1,1,0])
	
	init_hexagram(33, "䷠", [1,1,1,1,0,0])
	init_hexagram(34, "䷡", [0,0,1,1,1,1])
	init_hexagram(35, "䷢", [1,0,1,0,0,0])
	init_hexagram(36, "䷣", [0,0,0,1,0,1])
	init_hexagram(37, "䷤", [1,1,0,1,0,1])
	init_hexagram(38, "䷥", [1,0,1,0,1,1])
	init_hexagram(39, "䷦", [0,1,0,1,0,0])
	init_hexagram(40, "䷧", [0,0,1,0,1,0])
	init_hexagram(41, "䷨", [1,0,0,0,1,1])
	init_hexagram(42, "䷩", [1,1,0,0,0,1])
	init_hexagram(43, "䷪", [0,1,1,1,1,1])
	init_hexagram(44, "䷫", [1,1,1,1,1,0])
	init_hexagram(45, "䷬", [0,1,1,0,0,0])
	init_hexagram(46, "䷭", [0,0,0,1,1,0])
	init_hexagram(47, "䷮", [0,1,1,0,1,0])
	init_hexagram(48, "䷯", [0,1,0,1,1,0])
	
	init_hexagram(49, "䷰", [0,1,1,1,0,1])
	init_hexagram(50, "䷱", [1,0,1,1,1,0])
	init_hexagram(51, "䷲", [0,0,1,0,0,1])
	init_hexagram(52, "䷳", [1,0,0,1,0,0])
	init_hexagram(53, "䷴", [1,1,0,1,0,0])
	init_hexagram(54, "䷵", [0,0,1,0,1,1])
	init_hexagram(55, "䷶", [0,0,1,1,0,1])
	init_hexagram(56, "䷷", [1,0,1,1,0,0])
	init_hexagram(57, "䷸", [1,1,0,1,1,0])
	init_hexagram(58, "䷹", [0,1,1,0,1,1])
	init_hexagram(59, "䷺", [1,1,0,0,1,0])
	init_hexagram(60, "䷻", [0,1,0,0,1,1])
	init_hexagram(61, "䷼", [1,1,0,0,1,1])
	init_hexagram(62, "䷽", [0,0,1,1,0,0])
	init_hexagram(63, "䷾", [0,1,0,1,0,1])
	init_hexagram(64, "䷿", [1,0,1,0,1,0])

	
	#for i in range(0, 100):
	var lines = [yarrow_toss(),yarrow_toss(),yarrow_toss(),yarrow_toss(),yarrow_toss(),yarrow_toss()]
	var last = null
	for l in lines:
		var sprite = lineToSprite(l)
		get_node("result").add_child(sprite)
		if last:
			sprite.position.y = last.position.y + 35
		last = sprite
	var integer_hexagram = lines_to_hexagram(lines)
	var utf8 = PoolByteArray([228, 183, 127+integer_hexagram]).get_string_from_utf8()
	get_node("result_label").text = utf8 + "Hexagram " + str(integer_hexagram)
	load_text(integer_hexagram)
	
func load_text(integer_hexagram):
	var file = File.new()
	file.open("res://resources/hexagram-texts/ic" + str(integer_hexagram), File.READ)
	get_node("description").bbcode_text = file.get_as_text()

func lines_to_hexagram(lines):
	var binary = []
	for l in lines:
		binary.append(line_to_binary(l))
	for k in hexagrams.keys():
		if array_equal(binary, hexagrams[k]):
			return k
	return -1
		#var lines = [coin_toss(),coin_toss(),coin_toss(),coin_toss(),coin_toss(),coin_toss()]
func array_equal(a, b):
	var is_eq = true
	for i in range(0, len(a)):
		is_eq = is_eq and a[i] == b[i]
	return is_eq

func lineToSprite(val):
	if val == 6: return get_node("templates/to_yang").duplicate()
	if val == 7: return get_node("templates/yin").duplicate()
	if val == 8: return get_node("templates/to_yin").duplicate()
	if val == 9: return get_node("templates/yang").duplicate()

func line_to_binary(val):
	if val == 6: return 0 # unchanged
	if val == 7: return 0
	if val == 8: return 1 # unchanged
	if val == 9: return 1

func simple_coin_toss():
	var val = 0
	for i in range(0, 3):
		val += round(rand_range(2,3))
	return val

func coin_toss():
	var val = 0
	var special_coin = 0
	for i in range(0, 3):
		val += round(rand_range(2,3))
		if i == 0:
			special_coin = val
			
	
	if (6 == val) and (special_coin == 2):
		special_coin = round(rand_range(2,3))
		if special_coin == 2:
			return 6
		else:
			return 8
	else: if val == 7 and special_coin == 3:
		special_coin = round(rand_range(2,3))
		if special_coin == 3:
			return 7
		else:
			return 9
	return val
	
func yarrow_round(ys, round_n):
	ys[1] = int(floor(rand_range(floor(ys[0]/3),floor(ys[0]*2/3))))
	ys[4] = ys[0] - ys[1]
	ys[0] = ys[0] - ys[1] - ys[4]
	#if debug=="yes": printys(ys, "Separate into two")
	ys[3] = 1 
	ys[1] = ys[1] - ys[3] 
	#if debug=="yes": printys(ys, "and with one as human")
	ys[2] = int(ys[1]) % 4
	if ys[2] == 0:
	    ys[2] = 4
	ys[1] = ys[1] - ys[2]
	#if debug=="yes": printys(ys, "then 4 by 4 and sky behind ...")
	ys[5] = int(ys[4]) % 4
	if ys[5] == 0:
	    ys[5] = 4
	ys[4] = ys[4] - ys[5]
	#if debug=="yes": printys(ys, "then 4 by 4 and earth behind ...")
	ys[6] += ys[2] + ys[3] + ys[5]
	ys[2] = 0
	ys[3] = 0
	ys[5] = 0
	ys[0] = ys[1] + ys[4] 
	ys[1] = 0
	ys[4] = 0
	#if debug=="yes": printys(ys, "complete the cycle ...")
	return ys

func yarrow_toss():
	var ys = [0, 0, 0, 0, 0, 0, 0]
	ys[0] = 55 #  "The number of heaven and earth is 55"
	ys[0] = 49 # "only 49 is used"
	ys = yarrow_round(ys, 1)
	ys = yarrow_round(ys, 2)
	ys = yarrow_round(ys, 3)
	return floor(ys[0] / 4)