//deadEdge: first dead Edge to star //dir: direction where the wall will go on //wallDir: direction of the wall, left or right of the dir??? func checkForDeadWall(surface engine.Surface, deadEdge engine.Point, dir int8, wallDir int8) (bool, engine.Point) { possDead := deadEdge for { possDead = possDead.Add(engine.Direction(dir).Point()) if !surface.In(possDead) { return false, possDead } possField := surface[possDead.Y][possDead.X] possWallPos := possDead.Add(engine.Direction(wallDir).Point()) if !surface.In(possWallPos) { return false, possDead } possWall := surface[possWallPos.Y][possWallPos.X] if possField.Wall || possField.Point || !possWall.Wall { return false, possDead } else { dead, _ := DeadCorner(surface, possDead) if dead { return true, possDead } } } log.E(-1, "checkForDeadWall: end of For loop") return false, possDead }
/* try moving figure in specified direction. * Returns, if figure was moved and if figure moved a box. */ func (e *Engine) Move(dir Direction) (success bool, boxMoved int8) { success = false boxMoved = EMPTY cf := e.FigPos() // current figureposition nf := cf.Add(dir.Point()) // potential new figureposition if !e.Surface.In(nf) { log.D(e.Id, "Can not move: surface border") return } // check type of field of new figureposition switch f := e.Surface[nf.Y][nf.X]; { case f.Wall == true: log.D(e.Id, "Can not move: wall") return case f.Box != EMPTY: // if box nnf := nf.Add(dir.Point()) // potential new boxposition if !e.Surface.In(nnf) { log.D(e.Id, "Can not move: blocked box (surface border)") return } if e.Surface[nnf.Y][nnf.X].Dead { log.D(e.Id, "Can not move: Dead field") return } if e.Surface[nnf.Y][nnf.X].Wall || e.Surface[nnf.Y][nnf.X].Box != EMPTY { log.D(e.Id, "Can not move: blocked box") return } log.D(e.Id, "Move box") boxMoved = f.Box e.boxes[f.Box].SetPos(nnf) // nnf is position that box should move to, f.Box is current box e.reOrderBoxes(f.Box, dir) e.Surface[nnf.Y][nnf.X].Box = e.Surface[nf.Y][nf.X].Box fallthrough // go to next case statment to also move the figure case f.Box >= EMPTY: // actually always... var hist HistoryType hist.NewPos = nf hist.OldPos = cf hist.BoxMoved = boxMoved e.History = append(e.History, hist) e.Surface[nf.Y][nf.X].Box = e.Surface[cf.Y][cf.X].Box e.Surface[cf.Y][cf.X].Box = EMPTY e.figPos = nf // refresh figureposition success = true default: log.E(e.Id, "Unknown field") } return }
// load level from specified file (relative to binary file) func (e *Engine) LoadLevel(filename string) { raw, err := readLevelAsString(filename) if err != nil { panic(err) } // remove the "\r" from stupid windows files... raw = strings.Replace(raw, "\r", "", -1) // get single lines in an array lines := strings.Split(raw, "\n") e.Surface = Surface{{}} var field Field y := 0 boxId := int8(0) maxlen := 0 var char uint8 for _, line := range lines { if len(line) > 0 && line[0] == '#' && len(line) > maxlen { maxlen = len(line) } } for _, line := range lines { // filter empty lines and lines that do not start with '#' if len(line) == 0 || line[0] != '#' { continue } for x := 0; x < maxlen; x++ { char = '#' if x < len(line) { char = line[x] } switch char { case '#': field = Field{true, false, false, EMPTY} case ' ': field = Field{false, false, false, EMPTY} case '$': boxId++ field = Field{false, false, false, boxId} case '@': field = Field{false, false, false, EMPTY} e.figPos = NewPoint(x, y) case '.': field = Field{false, true, false, EMPTY} case '*': boxId++ field = Field{false, true, false, boxId} case '+': field = Field{false, true, false, EMPTY} e.figPos = NewPoint(x, y) default: log.E(e.Id, "Unknown character in level file: '%c'", char) } e.Surface[y] = append(e.Surface[y], field) if field.Point { e.points = append(e.points, NewPoint(x, y)) } if field.Box != EMPTY { box := NewBox(NewPoint(x, y), boxId) e.boxes[boxId] = &box e.boxesOrdered[boxId] = &box } } y++ e.Surface = append(e.Surface, []Field{}) } // the last sub-array of Surface is always empty, so remove it... if len(e.Surface[len(e.Surface)-1]) == 0 { e.Surface = e.Surface[:len(e.Surface)-1] } return }