package main

import (
	"fmt"
	"strings"
)

//////////////////////////////////////////////////////////////////////////////////////////////

type Quadtree struct {
	width, height int
	root          *node
}

type node struct {
	topLeftX, topLeftY int
	width, height      int
	content            int
	isLeaf             bool
	topLeftNode        *node
	topRightNode       *node
	bottomLeftNode     *node
	bottomRightNode    *node
}

// GetAsText permet d'afficher un quadtree sous forme textuelle pour vérifier
// visuellement qu'il est correct (attention, pour des arbres un peu grands
// la visualisation devient peu lisible).
func (q Quadtree) GetAsText(name string) (asText string) {

	asText += fmt.Sprintf("Quadtree %s\n", name)
	asText += fmt.Sprintf("width: %d, height: %d\n", q.width, q.height)

	if q.root != nil {
		asText += q.root.getAsText(0, 7)
	} else {
		asText += "ERROR: quadtree has no root node"
	}

	return
}

// getAsText permet d'afficher un nœud sous forme textuelle, c'est une méthode
// utilitaire pour construire GetAsText.
func (n node) getAsText(shift, step int) (asText string) {

	shiftString := strings.Repeat(" ", shift)
	stepString := strings.Repeat(" ", step)

	asText += fmt.Sprintf("[node, top: (%d, %d), width: %d, height: %d,", n.topLeftX, n.topLeftY, n.width, n.height)

	if n.isLeaf {
		asText += fmt.Sprintf(" leaf with content %d]", n.content)
	} else {
		asText += fmt.Sprintf("\n%s%stopLeft:     %s", stepString, shiftString, n.topLeftNode.checkAndGetAsText(shift+step+13, step))
		asText += fmt.Sprintf("\n%s%stopRight:    %s", stepString, shiftString, n.topRightNode.checkAndGetAsText(shift+step+13, step))
		asText += fmt.Sprintf("\n%s%sbottomLeft:  %s", stepString, shiftString, n.bottomLeftNode.checkAndGetAsText(shift+step+13, step))
		asText += fmt.Sprintf("\n%s%sbottomRight: %s", stepString, shiftString, n.bottomRightNode.checkAndGetAsText(shift+step+13, step))
		asText += fmt.Sprintf("\n%s]", shiftString)
	}

	return
}

// checkAndGetAsText permet de vérifier qu'un nœud existe bien et
// d'afficher une erreur si ce n'est pas le cas. C'est une méthode
// utilitaire pour contruire getAsText.
func (n *node) checkAndGetAsText(shift, step int) (asText string) {

	if n == nil {
		asText = "ERROR: unexpected nil node"
		return
	}

	asText = n.getAsText(shift, step)
	return
}

//////////////////////////////////////////////////////////////////////////////////////////////

func (q Quadtree) GetContent(topLeftX, topLeftY int, contentHolder [][]int) {

	//fmt.Println(contentHolder, topLeftX, topLeftY)

	// Cas de bases //
	if len(contentHolder) == 0 {
		return
	} else if len(contentHolder[0]) == 0 {
		return
	}

	// Toutes les cases sont mises à -1 par défaut, en attendant la récupération par GetNodeContent //
	for i := 0; i < len(contentHolder); i++ {
		for j := 0; j < len(contentHolder[0]); j++ {
			if contentHolder[i][j] == 0 {
				contentHolder[i][j] = -1
			}
		}
	}

	GetNodeContent(q.root, topLeftX, topLeftY, contentHolder)
	//fmt.Println(contentHolder)
}

func GetNodeContent(n *node, Origine_X, Origine_Y int, contentHolder [][]int) {

	// Cas de base, avec simplification (si height ou width vaut 0, le noeud n'entrera pas dans les deux boucles //
	if n.isLeaf {
		for i := 0; i < n.height && i+n.topLeftY < len(contentHolder)+Origine_Y; i++ {
			for j := 0; j < n.width && j+n.topLeftX < len(contentHolder[0])+Origine_X; j++ {
				//fmt.Println(i,j,n.topLeftY+i < len(contentHolder)+Origine_Y,n.topLeftX+j < len(contentHolder[0])+Origine_X , i+n.topLeftY>=Origine_Y, j+n.topLeftX>=Origine_X)
				if n.topLeftY+i < len(contentHolder)+Origine_Y && n.topLeftX+j < len(contentHolder[0])+Origine_X && i+n.topLeftY >= Origine_Y && j+n.topLeftX >= Origine_X {
					contentHolder[i+n.topLeftY-Origine_Y][j+n.topLeftX-Origine_X] = n.content
				}
			}
		}

	} else {
		// Cas récursif //
		GetNodeContent(n.topLeftNode, Origine_X, Origine_Y, contentHolder)
		GetNodeContent(n.topRightNode, Origine_X, Origine_Y, contentHolder)
		GetNodeContent(n.bottomLeftNode, Origine_X, Origine_Y, contentHolder)
		GetNodeContent(n.bottomRightNode, Origine_X, Origine_Y, contentHolder)
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////

func MakeFromArray(floorContent [][]int) (q Quadtree) {

	// Cas de bases //
	if len(floorContent) == 0 {
		return Quadtree{width: 0, height: 0, root: &node{topLeftX: 0, topLeftY: 0, width: 1, height: 0, isLeaf: true, content: -2}}
	}
	if len(floorContent[0]) == 0 {
		return Quadtree{width: 0, height: 0, root: &node{topLeftX: 0, topLeftY: 0, width: 0, height: 1, isLeaf: true, content: -2}}
	}
	if len(floorContent) == 1 && len(floorContent[0]) == 1 {
		return Quadtree{width: 1, height: 1, root: &node{topLeftX: 0, topLeftY: 0, width: 1, height: 1, isLeaf: true, content: floorContent[0][0]}}
	}

	// Initialisation du quadtree q //
	q = Quadtree{width: len(floorContent[0]), height: len(floorContent), root: nil}

	// Division de floorContent en 4 parties //
	topLeft := [][]int{}
	bottomLeft := [][]int{}
	topRight := [][]int{}
	bottomRight := [][]int{}
	middle_height := q.height / 2
	middle_width := q.width / 2

	for i := 0; i < middle_height; i++ {
		topLeft = append(topLeft, floorContent[i][:q.width/2])
		topRight = append(topRight, floorContent[i][q.width/2:])
	}
	for i := middle_height; i < len(floorContent); i++ {
		bottomLeft = append(bottomLeft, floorContent[i][:q.width/2])
		bottomRight = append(bottomRight, floorContent[i][q.width/2:])
	}

	// Création des 4 noeuds //
	topLeftN := MakeNode(topLeft, 0, 0)
	topRightN := MakeNode(topRight, 0, middle_width)
	bottomLeftN := MakeNode(bottomLeft, middle_height, 0)
	bottomRightN := MakeNode(bottomRight, middle_height, middle_width)

	// Vérifications des simplifications //
	if topLeftN.isLeaf && topRightN.isLeaf && bottomLeftN.isLeaf && bottomRightN.isLeaf {
		if topLeftN.content == topRightN.content && topLeftN.content == bottomLeftN.content && topLeftN.content == bottomRightN.content {
			q.root = &node{topLeftX: 0, topLeftY: 0, width: len(floorContent[0]), height: len(floorContent), isLeaf: true, content: topLeftN.content}
			return Quadtree{width: len(floorContent[0]), height: len(floorContent), root: q.root}
		}
	}

	//fmt.Println("hey", floorContent, q.height/2, q.width/2, tl, tr, bl, br, len(floorContent[0]), len(floorContent))

	// S'il n'y a pas de simplifications possibles //
	q.root = &node{topLeftX: 0, topLeftY: 0, width: len(floorContent[0]), height: len(floorContent),
		topLeftNode:     topLeftN,
		topRightNode:    topRightN,
		bottomLeftNode:  bottomLeftN,
		bottomRightNode: bottomRightN,
	}

	//fmt.Println(q.root.topLeftNode, q.root.topRightNode, q.root.bottomLeftNode, q.root.bottomRightNode)

	// Retour du quadtree complet //
	return Quadtree{width: len(floorContent[0]), height: len(floorContent), root: q.root}
}

func MakeNode(floorContent [][]int, Origine_y, Origine_x int) (n *node) {

	// Cas de bases //
	if len(floorContent) == 0 {
		return &node{topLeftX: Origine_x, topLeftY: Origine_y, width: 1, height: 0, isLeaf: true, content: -2}
	}
	if len(floorContent[0]) == 0 {
		return &node{topLeftX: Origine_x, topLeftY: Origine_y, width: 0, height: 1, isLeaf: true, content: -2}
	}
	//fmt.Println(len(floorContent), len(floorContent[0]))
	if len(floorContent) == 1 && len(floorContent[0]) == 1 {
		//fmt.Println(Origine_y, Origine_x, floorContent[0])
		return &node{topLeftX: Origine_x, topLeftY: Origine_y, width: 1, height: 1, isLeaf: true, content: floorContent[0][0]}
	}

	// Division de floorContent en 4 parties //
	topLeft := [][]int{}
	bottomLeft := [][]int{}
	topRight := [][]int{}
	bottomRight := [][]int{}
	middle_height := len(floorContent) / 2
	middle_width := len(floorContent[0]) / 2

	for i := 0; i < middle_height; i++ {
		topLeft = append(topLeft, floorContent[i][:len(floorContent[0])/2])
		topRight = append(topRight, floorContent[i][len(floorContent[0])/2:])
	}
	for i := middle_height; i < len(floorContent); i++ {
		bottomLeft = append(bottomLeft, floorContent[i][:len(floorContent[0])/2])
		bottomRight = append(bottomRight, floorContent[i][len(floorContent[0])/2:])
	}

	// Création des 4 sous-noeuds //
	topLeftN := MakeNode(topLeft, Origine_y, Origine_x)
	topRightN := MakeNode(topRight, Origine_y, Origine_x+middle_width)
	bottomLeftN := MakeNode(bottomLeft, Origine_y+middle_height, Origine_x)
	bottomRightN := MakeNode(bottomRight, Origine_y+middle_height, Origine_x+middle_width)

	// Vérifications des simplifications //
	if topLeftN.isLeaf && topRightN.isLeaf && bottomLeftN.isLeaf && bottomRightN.isLeaf {
		leaf := true
		ref := bottomRightN.content
		if topLeftN.content != -2 {
			ref = topLeftN.content
			if (topRightN.content != -2 && topRightN.content != topLeftN.content) || (bottomLeftN.content != -2 && bottomLeftN.content != topLeftN.content) || (bottomRightN.content != -2 && bottomRightN.content != topLeftN.content) {
				leaf = false
			}
		} else if topRightN.content != -2 {
			ref = topRightN.content
			if (bottomLeftN.content != -2 && bottomLeftN.content != topRightN.content) || (bottomRightN.content != -2 && bottomRightN.content != topRightN.content) {
				leaf = false
			}
		} else if bottomLeftN.content != -2 {
			ref = bottomLeftN.content
			if bottomRightN.content != -2 && bottomRightN.content != bottomLeftN.content {
				leaf = false
			}
		} else if bottomRightN.content == 2 {
			leaf = false
		}
		if leaf {
			return &node{topLeftX: Origine_x, topLeftY: Origine_y, width: len(floorContent[0]), height: len(floorContent), isLeaf: true, content: ref}
		}
	}

	//fmt.Println(Origine_y, Origine_x)
	//fmt.Println(tl, Origine_y, Origine_x, tr, Origine_y, Origine_x+middle_width, bl, Origine_y+middle_height, Origine_x, br, Origine_y+middle_height, Origine_x+middle_width)

	// S'il n'y a pas de simplification possibles //
	return &node{topLeftX: Origine_x, topLeftY: Origine_y, width: len(floorContent[0]), height: len(floorContent),
		topLeftNode:     topLeftN,
		topRightNode:    topRightN,
		bottomLeftNode:  bottomLeftN,
		bottomRightNode: bottomRightN,
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////

func main() {

	///// terrain vide /////

	make_attendu := Quadtree{width: 0, height: 0, root: nil}

	base_floor := [][]int{{}}
	tempo := MakeFromArray(base_floor)

	vide := [][]int{{}}
	tempo.GetContent(0, 0, vide)

	vide = [][]int{{}}
	make_attendu.GetContent(0, 0, vide)

	fmt.Println(tempo.GetAsText(""))

	///// terrain 1*1 //////

	make_attendu = Quadtree{width: 1, height: 1,
		root: &node{topLeftX: 0, topLeftY: 0, width: 1, height: 1, isLeaf: true, content: 4},
	}

	base_floor = [][]int{{4}}
	tempo = MakeFromArray(base_floor)

	vide = [][]int{{-1}}
	tempo.GetContent(0, 0, vide)

	vide = [][]int{{-1}}
	make_attendu.GetContent(0, 0, vide)

	fmt.Println(tempo.GetAsText(""))

	///// terrain 2*2 //////

	make_attendu = Quadtree{width: 2, height: 2,
		root: &node{topLeftX: 0, topLeftY: 0, width: 2, height: 2,
			topLeftNode:     &node{topLeftX: 0, topLeftY: 0, width: 1, height: 1, isLeaf: true, content: 1},
			topRightNode:    &node{topLeftX: 1, topLeftY: 0, width: 1, height: 1, isLeaf: true, content: 2},
			bottomLeftNode:  &node{topLeftX: 0, topLeftY: 1, width: 1, height: 1, isLeaf: true, content: 3},
			bottomRightNode: &node{topLeftX: 1, topLeftY: 1, width: 1, height: 1, isLeaf: true, content: 4},
		},
	}

	base_floor = [][]int{{1, 2}, {3, 4}}
	tempo = MakeFromArray(base_floor)

	vide = [][]int{{-1, -1}, {-1, -1}}
	tempo.GetContent(0, 0, vide)

	vide = [][]int{{-1, -1}, {-1, -1}}
	make_attendu.GetContent(0, 0, vide)

	fmt.Println(tempo.GetAsText(""))

	///// terrain 4*4 /////

	make_attendu = Quadtree{width: 4, height: 4,
		root: &node{topLeftX: 0, topLeftY: 0, width: 4, height: 4,
			topLeftNode: &node{topLeftX: 0, topLeftY: 0, width: 2, height: 2,
				topLeftNode:     &node{topLeftX: 0, topLeftY: 0, width: 1, height: 1, isLeaf: true, content: 0},
				topRightNode:    &node{topLeftX: 1, topLeftY: 0, width: 1, height: 1, isLeaf: true, content: 0},
				bottomLeftNode:  &node{topLeftX: 0, topLeftY: 1, width: 1, height: 1, isLeaf: true, content: 0},
				bottomRightNode: &node{topLeftX: 1, topLeftY: 1, width: 1, height: 1, isLeaf: true, content: 0},
			},
			topRightNode: &node{topLeftX: 2, topLeftY: 0, width: 2, height: 2,
				topLeftNode:     &node{topLeftX: 2, topLeftY: 0, width: 1, height: 1, isLeaf: true, content: 1},
				topRightNode:    &node{topLeftX: 3, topLeftY: 0, width: 1, height: 1, isLeaf: true, content: 1},
				bottomLeftNode:  &node{topLeftX: 2, topLeftY: 1, width: 1, height: 1, isLeaf: true, content: 0},
				bottomRightNode: &node{topLeftX: 3, topLeftY: 1, width: 1, height: 1, isLeaf: true, content: 1},
			},
			bottomLeftNode: &node{topLeftX: 0, topLeftY: 2, width: 2, height: 2,
				topLeftNode:     &node{topLeftX: 0, topLeftY: 2, width: 1, height: 1, isLeaf: true, content: 1},
				topRightNode:    &node{topLeftX: 1, topLeftY: 2, width: 1, height: 1, isLeaf: true, content: 1},
				bottomLeftNode:  &node{topLeftX: 0, topLeftY: 3, width: 1, height: 1, isLeaf: true, content: 1},
				bottomRightNode: &node{topLeftX: 1, topLeftY: 3, width: 1, height: 1, isLeaf: true, content: 1},
			},
			bottomRightNode: &node{topLeftX: 2, topLeftY: 2, width: 2, height: 2,
				topLeftNode:     &node{topLeftX: 2, topLeftY: 2, width: 1, height: 1, isLeaf: true, content: 0},
				topRightNode:    &node{topLeftX: 3, topLeftY: 2, width: 1, height: 1, isLeaf: true, content: 0},
				bottomLeftNode:  &node{topLeftX: 2, topLeftY: 3, width: 1, height: 1, isLeaf: true, content: 1},
				bottomRightNode: &node{topLeftX: 3, topLeftY: 3, width: 1, height: 1, isLeaf: true, content: 0},
			},
		},
	}

	base_floor = [][]int{{0, 0, 1, 1}, {0, 0, 0, 1}, {1, 1, 0, 0}, {1, 1, 1, 0}}
	tempo = MakeFromArray(base_floor)

	vide = [][]int{{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}
	tempo.GetContent(0, 0, vide)

	vide = [][]int{{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}
	make_attendu.GetContent(0, 0, vide)

	fmt.Println(tempo.GetAsText(""))

	///// terrain 1*2 /////

	make_attendu = Quadtree{width: 2, height: 1,
		root: &node{topLeftX: 0, topLeftY: 0, width: 2, height: 1,
			topLeftNode:     &node{topLeftX: 0, topLeftY: 0, width: 1, height: 0, isLeaf: true, content: 0},
			topRightNode:    &node{topLeftX: 1, topLeftY: 0, width: 1, height: 0, isLeaf: true, content: 0},
			bottomLeftNode:  &node{topLeftX: 0, topLeftY: 0, width: 1, height: 1, isLeaf: true, content: 1},
			bottomRightNode: &node{topLeftX: 1, topLeftY: 0, width: 1, height: 1, isLeaf: true, content: 2},
		},
	}

	base_floor = [][]int{{1, 2}}
	tempo = MakeFromArray(base_floor)

	vide = [][]int{{-1, -1}}
	tempo.GetContent(0, 0, vide)

	vide = [][]int{{-1, -1}}
	make_attendu.GetContent(0, 0, vide)

	fmt.Println(tempo.GetAsText(""))

	///// terrain 4*3 //////

	make_attendu = Quadtree{width: 4, height: 3,
		root: &node{topLeftX: 0, topLeftY: 0, width: 4, height: 3,
			topLeftNode: &node{topLeftX: 0, topLeftY: 0, width: 2, height: 1,
				topLeftNode:     &node{topLeftX: 0, topLeftY: 0, width: 1, height: 0, isLeaf: true, content: 0},
				topRightNode:    &node{topLeftX: 1, topLeftY: 0, width: 1, height: 0, isLeaf: true, content: 0},
				bottomLeftNode:  &node{topLeftX: 0, topLeftY: 0, width: 1, height: 1, isLeaf: true, content: 0},
				bottomRightNode: &node{topLeftX: 1, topLeftY: 0, width: 1, height: 1, isLeaf: true, content: 1},
			},
			topRightNode: &node{topLeftX: 2, topLeftY: 0, width: 2, height: 1,
				topLeftNode:     &node{topLeftX: 2, topLeftY: 0, width: 1, height: 0, isLeaf: true, content: 0},
				topRightNode:    &node{topLeftX: 3, topLeftY: 0, width: 1, height: 0, isLeaf: true, content: 0},
				bottomLeftNode:  &node{topLeftX: 2, topLeftY: 0, width: 1, height: 1, isLeaf: true, content: 2},
				bottomRightNode: &node{topLeftX: 3, topLeftY: 0, width: 1, height: 1, isLeaf: true, content: 3},
			},
			bottomLeftNode: &node{topLeftX: 0, topLeftY: 1, width: 2, height: 2,
				topLeftNode:     &node{topLeftX: 0, topLeftY: 1, width: 1, height: 1, isLeaf: true, content: 0},
				topRightNode:    &node{topLeftX: 1, topLeftY: 1, width: 1, height: 1, isLeaf: true, content: 1},
				bottomLeftNode:  &node{topLeftX: 0, topLeftY: 2, width: 1, height: 1, isLeaf: true, content: 0},
				bottomRightNode: &node{topLeftX: 1, topLeftY: 2, width: 1, height: 1, isLeaf: true, content: 1},
			},
			bottomRightNode: &node{topLeftX: 2, topLeftY: 1, width: 2, height: 2,
				topLeftNode:     &node{topLeftX: 2, topLeftY: 1, width: 1, height: 1, isLeaf: true, content: 2},
				topRightNode:    &node{topLeftX: 3, topLeftY: 1, width: 1, height: 1, isLeaf: true, content: 3},
				bottomLeftNode:  &node{topLeftX: 2, topLeftY: 2, width: 1, height: 1, isLeaf: true, content: 2},
				bottomRightNode: &node{topLeftX: 3, topLeftY: 2, width: 1, height: 1, isLeaf: true, content: 3},
			},
		},
	}

	base_floor = [][]int{{0, 1, 2, 3}, {0, 1, 2, 3}, {0, 1, 2, 3}}
	tempo = MakeFromArray(base_floor)

	vide = [][]int{{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}
	tempo.GetContent(0, 0, vide)

	vide = [][]int{{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}
	make_attendu.GetContent(0, 0, vide)

	fmt.Println(tempo.GetAsText(""))

	///// fichier 8x8 /////

	base_floor = [][]int{
		{0, 0, 0, 3, 3, 1, 1, 1},
		{0, 0, 0, 3, 3, 1, 1, 1},
		{0, 0, 0, 3, 3, 1, 1, 1},
		{0, 0, 0, 3, 3, 1, 1, 1},
		{0, 0, 0, 3, 3, 3, 3, 3},
		{0, 0, 0, 3, 3, 3, 3, 3},
		{0, 0, 0, 3, 3, 1, 1, 1},
		{0, 0, 0, 3, 3, 1, 1, 1}}

	tempo = MakeFromArray(base_floor)
	vide = [][]int{{-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}
	tempo.GetContent(0, 0, vide)

	fmt.Println(tempo.GetAsText("")) // décommenter pour tester

	///// fichier 8x9 /////

	base_floor = [][]int{
		{0, 0, 0, 3, 3, 1, 1, 1, 2},
		{0, 0, 0, 3, 3, 1, 1, 1, 2},
		{0, 0, 0, 3, 3, 1, 1, 1, 2},
		{0, 0, 0, 3, 3, 1, 1, 1, 2},
		{0, 0, 0, 3, 3, 3, 3, 3, 2},
		{0, 0, 0, 3, 3, 3, 3, 3, 2},
		{0, 0, 0, 3, 3, 1, 1, 1, 2},
		{0, 0, 0, 3, 3, 1, 1, 1, 2}}

	tempo = MakeFromArray(base_floor)
	vide = [][]int{{-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1}}
	tempo.GetContent(0, 0, vide)

	fmt.Println(tempo.GetAsText("")) // décommenter pour tester

	///// fichier validation /////

	base_floor = [][]int{
		{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
		{1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 1, 2, 1, 2, 2, 2, 1},
		{0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0},
		{1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1},
		{0, 2, 0, 2, 0, 2, 2, 1, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0},
		{1, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 0, 2, 0, 1, 2, 2, 2, 1},
		{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}}

	tempo = MakeFromArray(base_floor)
	vide = [][]int{{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}
	tempo.GetContent(0, 0, vide)

	//fmt.Println(tempo.GetAsText("")) // décommenter pour tester

	///// test full reduction /////

	base_floor = [][]int{
		{2, 2, 2, 2, 2, 2, 2, 2},
		{2, 2, 2, 2, 2, 2, 2, 2}}

	tempo = MakeFromArray(base_floor)
	vide = [][]int{{-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}
	tempo.GetContent(0, 0, vide)
	fmt.Println(tempo.GetAsText(""))

	///// test reduction partielle /////

	base_floor = [][]int{
		{3, 3, 3, 3, 2, 2, 1, 0},
		{2, 2, 2, 2, 2, 2, 2, 2}}

	tempo = MakeFromArray(base_floor)
	vide = [][]int{{-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}
	tempo.GetContent(0, 0, vide)
	fmt.Println(tempo.GetAsText(""))
}
