示例#1
0
文件: tree.go 项目: Ken1JF/sgf
// AddAProp adds a property to a node.
// AddAProp changes a BlackMoveNode or a WhiteMoveNode into an InteriorNode,
// when a property is added, making the B or W property the first in the list.
func (gamT *GameTree) AddAProp(n TreeNodeIdx, pv PropertyValue) (err ah.ErrorList) {
	mov := gamT.treeNodes[n].propListOrNodeLoc
	if gamT.treeNodes[n].TNodType == BlackMoveNode {
		var movPV *PropertyValue = new(PropertyValue)
		movPV.StrValue = SGFCoords(ah.NodeLoc(mov), gamT.IsFF4())
		movPV.NextProp = nilPropIdx
		movPV.PropType = B_idx
		movPV.ValType = Move
		gamT.treeNodes[n].TNodType = InteriorNode
		gamT.treeNodes[n].propListOrNodeLoc = nilPropIdx
		err := gamT.addProperty(*movPV, n)
		if len(err) != 0 {
			err.Add(ah.NoPos, "adding B property "+err.Error())
		}
	} else if gamT.treeNodes[n].TNodType == WhiteMoveNode {
		var movPV *PropertyValue = new(PropertyValue)
		movPV.StrValue = SGFCoords(ah.NodeLoc(mov), gamT.IsFF4())
		movPV.NextProp = nilPropIdx
		movPV.PropType = W_idx
		movPV.ValType = Move
		gamT.treeNodes[n].TNodType = InteriorNode
		gamT.treeNodes[n].propListOrNodeLoc = nilPropIdx
		err := gamT.addProperty(*movPV, n)
		if len(err) != 0 {
			err.Add(ah.NoPos, "adding W property "+err.Error())
		}
	}
	err = gamT.addProperty(pv, n)
	if len(err) != 0 {
		err.Add(ah.NoPos, "adding property "+err.Error())
	}
	return err
}
示例#2
0
文件: printer.go 项目: Ken1JF/sgf
//	writeTree writes a .sgf tree from the treeNodes array
//		w is a buffered I/O writer
//		n is the TreeNodeIdx of the root of this tree
//		needs is a bool that is true when a \n is needed
//		nMov keeps a count of moves per line.
//	writeTree first writes one node, then recursively calls writeTree
//	writeTree is only called from writeGame, which has one active call, and one that is never reached (&& false)
func (p *GameTree) writeTree(w *bufio.Writer, n TreeNodeIdx, needs bool, nMov int, nMovPerLine int) (err error) {
	defer u(tr("writeTree"))
	if needs == true {
		if nMov > 0 {
			err = w.WriteByte('\n')
			nMov = 0
		}
		err = w.WriteByte('(')
	}
	if err == nil {
		if nMov == nMovPerLine {
			err = w.WriteByte('\n')
			nMov = 0
		}
		err = w.WriteByte(';')
		// write the node
		typ := p.treeNodes[n].TNodType
		switch typ {
		case GameInfoNode:
			//           fmt.Println("writing GameInfoNode\n")
			err = p.writeProperties(w, n, true)
		case InteriorNode:
			//           fmt.Println("writing InteriorNode\n")
			err = p.writeProperties(w, n, false)
		case BlackMoveNode:
			_, err = w.WriteString("B[")
			_, err = w.Write(SGFCoords(ah.NodeLoc(p.treeNodes[n].propListOrNodeLoc), p.IsFF4()))
			err = w.WriteByte(']')
			nMov += 1
		case WhiteMoveNode:
			_, err = w.WriteString("W[")
			_, err = w.Write(SGFCoords(ah.NodeLoc(p.treeNodes[n].propListOrNodeLoc), p.IsFF4()))
			err = w.WriteByte(']')
			nMov += 1
		default:
			fmt.Println("*** unsupported TreeNodeType in writeTree")
			err = errors.New("writeTree: unsupported TreeNodeType" + strconv.FormatInt(int64(typ), 10))
			return err
		}
		if err == nil {
			// write the children
			lastCh := p.treeNodes[n].Children
			if lastCh != nilTreeNodeIdx && err == nil {
				ch := p.treeNodes[lastCh].NextSib
				chNeeds := (lastCh != ch)
				err = p.writeTree(w, ch, chNeeds, nMov, nMovPerLine)
				for ch != lastCh && err == nil {
					ch = p.treeNodes[ch].NextSib
					//					nMov += 1
					err = p.writeTree(w, ch, chNeeds, nMov, nMovPerLine)
				}
			}
			if (err == nil) && (needs == true) {
				err = w.WriteByte(')')
			}
		}
	}
	return err
}
示例#3
0
文件: game.go 项目: Ken1JF/sgf
// GetMove returns the move at a node
func (gamT *GameTree) GetMove(n TreeNode) (nl ah.NodeLoc, c ah.PointStatus, err ah.ErrorList) {
	if n.TNodType == BlackMoveNode {
		nl, c = ah.NodeLoc(n.propListOrNodeLoc), ah.Black
	} else if n.TNodType == WhiteMoveNode {
		nl, c = ah.NodeLoc(n.propListOrNodeLoc), ah.White
	} else if n.TNodType == InteriorNode {
		OK := false
		lastProp := n.propListOrNodeLoc
		if lastProp != nilPropIdx {
			pl := gamT.propertyValues[lastProp].NextProp
			prop := gamT.propertyValues[pl]
			process := func(prop PropertyValue) {
				if prop.PropType == B_idx {
					OK = true
					c = ah.Black
					nl, err = SGFPoint(prop.StrValue)
				} else if prop.PropType == W_idx {
					OK = true
					c = ah.White
					nl, err = SGFPoint(prop.StrValue)
				} else {
					pl = prop.NextProp
				}
			}
			// pprocess first prop.
			process(prop)
			if !OK {
				for (pl != lastProp) && (err == nil) {
					pl := gamT.propertyValues[pl].NextProp
					prop := gamT.propertyValues[pl]
					// pprocess next prop.
					process(prop)
					if OK {
						break
					}
				}
			}
		}
		if !OK {
			err.Add(ah.NoPos, "sgf/GetMove: move property not found in interior node")
		}
	} else {
		// TODO: support moves with other properties
		nl = ah.IllegalNodeLoc
		c = ah.Unocc
		err.Add(ah.NoPos, "sgf/GetMove: not a move node or interior node")
	}
	return nl, c, err
}
示例#4
0
文件: tree.go 项目: Ken1JF/sgf
// FindChild returns the index of a child of with a move at mov
func (gamT *GameTree) FindChild(par TreeNodeIdx, mov ah.NodeLoc) (found TreeNodeIdx) {
	found = nilTreeNodeIdx
	var ch TreeNodeIdx = nilTreeNodeIdx
	var p_idx PropIdx = nilPropIdx
	checkMov := func() {
		if gamT.propertyValues[p_idx].PropType == B_idx || gamT.propertyValues[p_idx].PropType == W_idx {
			mv, err := SGFPoint(gamT.propertyValues[p_idx].StrValue)
			if len(err) != 0 {
				return
			}
			if mv == mov {
				found = ch // set found to the child index
			}
		}
	}
	lookFor := func() {
		typ := gamT.treeNodes[ch].TNodType
		switch typ {
		case InteriorNode:
			var tail_p PropIdx = gamT.treeNodes[ch].propListOrNodeLoc
			if tail_p != nilPropIdx {
				p_idx = tail_p
				// check for mov
				checkMov()
				for p_idx != tail_p && found == nilTreeNodeIdx {
					p_idx = gamT.propertyValues[p_idx].NextProp
					// check for mov
					checkMov()
				}
			}
		case BlackMoveNode, WhiteMoveNode:
			// TODO: need to check the mov color? currently, no
			if ah.NodeLoc(gamT.treeNodes[ch].propListOrNodeLoc) == mov {
				found = ch
			}
		default:
		}
	}
	tail := gamT.treeNodes[par].Children
	if tail != nilTreeNodeIdx { // check if any children
		ch = gamT.treeNodes[tail].NextSib // get the first child
		// look for a move at mov
		lookFor()
		for ch != tail && found == nilTreeNodeIdx {
			ch = gamT.treeNodes[ch].NextSib // get the next child
			// look for a move at mov
			lookFor()
		}
	}
	return found
}
示例#5
0
文件: tree.go 项目: Ken1JF/sgf
func DoAddLabels(gamT *GameTree, nodIdx TreeNodeIdx) {
	lastCh := gamT.treeNodes[nodIdx].Children
	if lastCh != nilTreeNodeIdx {
		ch := gamT.treeNodes[lastCh].NextSib
		i := 1
		for ch != lastCh {
			nodLoc, _, _ := gamT.GetMove(gamT.treeNodes[ch])
			if nodLoc != ah.PassNodeLoc {
				i += 1
			}
			ch = gamT.treeNodes[ch].NextSib
		}
		if i > 1 {
			Labels := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
			//Labels := [26]byte{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}
			var sep = make([]byte, 2)
			var colon = make([]byte, 1)
			sep[0] = ']'
			sep[1] = '['
			colon[0] = ':'
			// fmt.Println("i =", i)
			needsLabel := false
			if gamT.treeNodes[nodIdx].TNodType == BlackMoveNode {
				// change to InteriorNode and Add B_idx property
				nodLoc := ah.NodeLoc(gamT.treeNodes[nodIdx].propListOrNodeLoc)
				if nodLoc != ah.PassNodeLoc {
					pv := PropertyValue{StrValue: SGFCoords(nodLoc, gamT.IsFF4()), NextProp: nilPropIdx, PropType: B_idx, ValType: Move}
					gamT.treeNodes[nodIdx].TNodType = InteriorNode
					gamT.treeNodes[nodIdx].propListOrNodeLoc = nilPropIdx
					_ = gamT.addProperty(pv, nodIdx)
					needsLabel = true
				}
			} else if gamT.treeNodes[nodIdx].TNodType == WhiteMoveNode {
				// change to InteriorNode and Add W_idx property
				nodLoc := ah.NodeLoc(gamT.treeNodes[nodIdx].propListOrNodeLoc)
				if nodLoc != ah.PassNodeLoc {
					pv := PropertyValue{StrValue: SGFCoords(nodLoc, gamT.IsFF4()), NextProp: nilPropIdx, PropType: W_idx, ValType: Move}
					gamT.treeNodes[nodIdx].TNodType = InteriorNode
					gamT.treeNodes[nodIdx].propListOrNodeLoc = nilPropIdx
					_ = gamT.addProperty(pv, nodIdx)
					needsLabel = true
				}
			} else {
				needsLabel = true
			}
			if needsLabel {
				// Build the LB property
				pv := PropertyValue{StrValue: nil, NextProp: nilPropIdx, PropType: LB_idx, ValType: ListOfCompPoint_simpTest}
				lastCh = gamT.treeNodes[nodIdx].Children
				ch = gamT.treeNodes[lastCh].NextSib
				j := 0
				for ch != lastCh {
					nodLoc, _, _ := gamT.GetMove(gamT.treeNodes[ch])
					if nodLoc != ah.PassNodeLoc {
						// fmt.Printf(" StrValue = %s\n", string(pv.StrValue))
						pv.StrValue = append(pv.StrValue, SGFCoords(nodLoc, gamT.IsFF4())...)
						// fmt.Printf(" StrValue = %s\n", string(pv.StrValue))
						pv.StrValue = append(pv.StrValue, colon[0])
						// fmt.Printf(" StrValue = %s\n", string(pv.StrValue))
						pv.StrValue = append(pv.StrValue, Labels[j])
						// fmt.Printf(" StrValue = %s\n", string(pv.StrValue))
						j += 1
						if j < i {
							pv.StrValue = append(pv.StrValue, sep...)
							// fmt.Printf(" StrValue = %s\n", string(pv.StrValue))
						}
					}
					ch = gamT.treeNodes[ch].NextSib
				}
				nodLoc, _, _ := gamT.GetMove(gamT.treeNodes[ch])
				if nodLoc != ah.PassNodeLoc {
					pv.StrValue = append(pv.StrValue,
						SGFCoords(nodLoc, gamT.IsFF4())...)
					pv.StrValue = append(pv.StrValue, colon[0])
					pv.StrValue = append(pv.StrValue, Labels[j])
					// fmt.Printf(" StrValue = %s\n", string(pv.StrValue))
				}
				//add the LB property
				_ = gamT.addProperty(pv, nodIdx)
				NumberOfAddedLabels += 1
			}
		}
	}
}