游戏老虎吃绵羊 -- lua

简介:

游戏双方分别使用绵羊(S)和老虎(T)

                                             图 1
图中6S代表当前为位置上有6只绵羊

除了如图所示为6S的点外,其他点只能同时有一个动物,6S点可容纳任意数量的动物,但必须是同一种类,两只老虎不能同时出现在同一位置上

绵羊每次可以沿着连线移动一个位置,老虎每次也可以仅移动一个位置,但如果该直线方向上相邻是绵羊,且距离为2的点为空时,老虎可以跨过绵羊跳到该位置,并吃掉绵羊

当绵羊数为0时老虎胜,老虎无法移动时绵羊胜,如图2,(3, 2)位置上的老虎跳到(5, 2)吃掉(4,2)上的一只绵羊

                                            图 2

绵羊和老虎轮流移动一个棋子,每局开始以如图1所示开始,且老虎先走。


游戏操作:


提示:It's turn to tigger

输入:老虎所在行 (回车)老虎所在列(回车)

提示: Input move target

输入:要移动到的位置行(回车),列(回车)


完成后切换到羊

提示: It's turn to sheep

输入:羊所在行(回车),列(回车)

如果该位置有多只羊

提示Select piece,并列出该位置上羊的索引如1 2 3 4 5 6

输入:羊的索引 ,如1(回车)

提示:Input move target

输入:要移动到的位置行(回车),列(回车)

完成羊的移动,切换到老虎,交换操作直到游戏结束,如

Sheep win


源代码:

下载连接

http://download.csdn.net/detail/piaobotudou/7718661

Array类:

--class  array --

Array = {
	nextIdx = 1,
}

function Array:new(o)
	o = o or {}
	setmetatable(o, self)
	self.__index = self
	o.content = {}

	for i=1, #o do
		if o[i] then
			o:push_back(o[i])
		end
	end
	return o;
end


function Array:count()
	return self.nextIdx - 1
end

function Array:toIndex(idx)
	i = tonumber(idx)
	if i and i>0 and i<=self:count() then
		return i
	end
	return nil
end


function Array:push_back(a)
	self.content[self.nextIdx] = a
	self.nextIdx = self.nextIdx + 1
end

function Array:pop_back()
	if self:count() > 0 then
		self.nextIdx = self.nextIdx - 1
		res = self.content[self.nextIdx]
		self.content[self.nextIdx] = nil
		return res
	end
	return nil
end

function Array:cleanup()
	for i=1, #self.content do
		self.content[i] = nil
	end
	self.nextIdx = 1
end

function Array:find(item)
	for i=1, self:count() do
		if self.content[i] == item then
			return i
		end
	end
	return nil
end

function Array:remove_item(item)
	idx = self:find(item)
	if idx then
		self:remove(idx)
	end
end

function Array:insert(idx, a)
	idx = self:toIndex(idx)
	if idx then
		local cpl
		local cp2
		cp1 = a
		for i=idx, self:count() do
			cp2 = self.content[i]
			self.content[i] = cp1
			cp1 = cp2
		end
		self:push_back(cp1)
	end
end

function Array:getAt(idx)
	i = self:toIndex(idx)
	if i then
		return self.content[idx]
	end
	return nil
end

function Array:remove(idx)
	idx = self:toIndex(idx)
	if idx then
		for i=idx, self:count()-1 do
			self.content[i] = self.content[i+1]
		end
		self:pop_back()
	end
end

--Insert at 1
function Array:push_front(a)
	self:insert(1, a)
end

function Array:pop_front()
	res = self.content[1]
	self:remove(1)
	return res
end

function Array:print()
	local s = "";
	if self:count() > 0 then
		s = s..self:getAt(1)
	end
	for i=2, self:count() do
		s = s.." ".. self:getAt(i)
	end
	print(s)
end

core.lua

--Chess board class---
--Include Line & Node --

PIECETYPE = {
	none = 0,
	tigger = 1,
	sheep = 2
}
--piece define--
Piece = {}
Piece.name = "unnamed piece"
Piece.r = -1 --row
Piece.c = -1 --col
Piece.idx = -1
Piece.dead = false
Piece.type = none 
function Piece:new(o)
 	o = o or {}
	setmetatable(o, self)
	self.__index = self
	return o
end

PieceTigger = Piece:new()
PieceTigger.name = "Tigger"
Piece.type = PIECETYPE.tigger

PieceSheep = Piece:new()
PieceSheep.name = "Sheep"
PieceSheep.type = PIECETYPE.sheep

PieceManager = {tiggers=nil,sheeps=nil}
function PieceManager:new(o)
	o = o or {}
	setmetatable(o, self)
	self.__index = self;
	o.tiggers = {}
	o.sheeps = {}
	return o
end
function PieceManager:makealive()
	for i=1,#self.tiggers do
		self.tiggers[i].dead = false
	end
	for i=1,#self.sheeps do
		self.sheeps[i].dead = false
	end
end

function PieceManager:getpiece(idx)
	if idx < 25 then
		return self.sheeps[idx]
	elseif idx<27 then
		return self.tiggers[idx - 24]
	else
		return nil
	end
end

function PieceManager:init(tn, sn)
	for i=1, tn do
		self.tiggers[i] = PieceTigger:new()
		self.tiggers[i].idx = i + sn
		self.tiggers[i].name = "tigger "..(i-sn)
	end
	for i=1,sn do
		self.sheeps[i] = PieceSheep:new()
		self.sheeps[i].idx = i
		self.sheeps[i].name = "sheep "..i
	end
end

--class Line--

Line = {}
Line.nodes = nil
function Line:new(o)
	o = o or {}
	setmetatable(o, self)
	self.__index = self
	o.nodes = {}
	return o
end


function Line:append(node)
	self.nodes[(#(self.nodes)) + 1] = node
end


--
--class Node--
--
dofile("array.lua")
Node = {}
Node.lines = nil
Node.pieces = nil 
Node.capacity = 1

function Node:new(o)
	o = o or {}
	setmetatable(o, self)
	self.__index = self
	o.pieces = Array:new()
	o.lines = {}
	return o
end
function Node:canaddpiece()
	return self.pieces:count() < self.capacity
end
function Node:empty()
	return self.pieces:count() == 0
end

function Node:firstpiece()
	if self:empty() then
		return nil
	else
		return self.pieces:getAt(1);
	end
end

function Node:add(l, i)
	self.lines[#self.lines + 1] = {line = l, idx = i}
end

function Node:isonline(lidx)
	for i = 1, #self.lines do
		if self.lines[i].line == lidx then
			return true
		end
	end
	return false
end

function Node:getidxofline(lidx)
	for i=1, #self.lines do
		if self.lines[i].line == lidx then
			return self.lines[i].idx
		end
	end
	return nil
end
function Node:printlines()
	print( "LinesCount: "..#self.lines)
	str = ""
	for i=1, #self.lines do
		str = str .. self.lines[i].line.." "
	end
	print(str)
end

function Node:getline(otherNode)
	--self:printlines()
	--otherNode:printlines()
	for i=1, #self.lines do
		if otherNode:isonline(self.lines[i].line) then
			return self.lines[i].line
		end
	end
	return nil
end


--Board--
--[[
  	1       2        3      4        5    
 	 --------/-------.,------/-------.     6
  	|`.     |     ,`|`      |     ,`| 
  	|  `.   |   ,'  |  `.   |   ,'  | 
  	|', |  -    |    ', |  -    | 
  	|      `|,'     |      `|,'     | 
  	--------|---------------|-------- 	7
  	|    ,' | `.    |    ,' | `.    | 
  	|  ,-   |   `,  |  ,-   |   `,  | 
  	| /     |     ',| /     |     ',| 
  	-`------|-------|-------|-------. 	8
11  |`.     |     ,`|`.     |     ,`|   16
  	|  `.   |   ,'  |  `.   |   ,'  | 
  	|    ', |  -    |    ', |  -    | 
  	|      `|,'     |      `|,'     | 
  	--------|---------------|-------- 	9
  	|    ,' | `.    |    ,' | `.    | 
  	|  ,-   |   `,  |  ,-   |   `,  | 
  	| /     |     ',| /     |     ',| 
  	-`------\-------'`------\-------' 	10
12				13 	   14  				15
----]]
Board = {}
Board.nodes = nil
Board.lines = nil

function Board:new(o)
	o = o or {}
	setmetatable(o, self)
	self.__index = self
	o.nodes = {}
	o.lines = {}
	return o
end

function rowcolToIndex(r, c)
	return (r-1)*5 + c
end
function indexToRow(idx)
	return math.ceil(idx/5)
end
function indexToCol(idx)
	return idx - (indexToRow(idx) - 1)*5
end

function Board:appendNodeToLine(lidx, r, c)
	self.lines[lidx]:append(rowcolToIndex(r, c))
	self.nodes[r][c]:add(lidx, #self.lines[lidx].nodes)
end

function Board:Init()
	for i=1, 5 do
		self.nodes[i] = {}
		for j=1, 5 do
			self.nodes[i][j] = Node:new()
		end
	end

	self.nodes[2][2].capacity = 100
	self.nodes[4][2].capacity = 100
	self.nodes[2][4].capacity = 100
	self.nodes[4][4].capacity =	100

	for i=1,16 do
		self.lines[i] = Line:new()
	end
	
	for i=1, 5 do
		for k=1,5 do
			self:appendNodeToLine(i, k, i)
			self:appendNodeToLine(i+5, i, k)
		end
	end
	self:appendNodeToLine(11, 3, 1)
	self:appendNodeToLine(11, 2, 2)
	self:appendNodeToLine(11, 1, 3)
	
	self:appendNodeToLine(12, 5, 1)
	self:appendNodeToLine(12, 4, 2)
	self:appendNodeToLine(12, 3, 3)
	self:appendNodeToLine(12, 2, 4)
	self:appendNodeToLine(12, 1, 5)

	self:appendNodeToLine(13, 5, 3)
	self:appendNodeToLine(13, 4, 4)
	self:appendNodeToLine(13, 3, 5)
	
	self:appendNodeToLine(14, 3, 1)
	self:appendNodeToLine(14, 4, 2)
	self:appendNodeToLine(14, 5, 3)
	
	self:appendNodeToLine(15, 1, 1)
	self:appendNodeToLine(15, 2, 2)
	self:appendNodeToLine(15, 3, 3)
	self:appendNodeToLine(15, 4, 4)
	self:appendNodeToLine(15, 5, 5)

	self:appendNodeToLine(16, 1, 3)
	self:appendNodeToLine(16, 2, 4)
	self:appendNodeToLine(16, 3, 5)

	
end






--GAME--
Game = {}
Game.board = nil 
Game.pieces = nil--PieceManager:new()
Game.turn = PIECETYPE.tigger
Game.curpick = -1

function Game:new(o)
	o = o or {}
	setmetatable(o, self)
	self.__index = self
	o.board = Board:new()
	o.pieces = PieceManager:new()
	return o
end

function Game:AddPieceToBoard(r, c, idx, bt)
	self.board.nodes[r][c].pieces:push_back(idx)
	--print(r.." "..c.." "..idx)
	if bt then
		self.pieces.tiggers[idx-24].r = r
		self.pieces.tiggers[idx-24].c = c
	else
		self.pieces.sheeps[idx].r = r
		self.pieces.sheeps[idx].c = c
	end
end

function Game:restart()
	for i=1, 5 do
		for j=1,5 do
			self.board.nodes[i][j].pieces:cleanup()
		end
	end
--	for i, v in ipairs(self.board.nodes) do

--	end
	self.pieces:makealive()
		
	for i=1,6 do
		self:AddPieceToBoard(2, 2, i, false)
		self:AddPieceToBoard(2, 4, i+6, false)
		self:AddPieceToBoard(4, 2, i+12, false)
		self:AddPieceToBoard(4, 4, i+18, false)
	end


	--self.board.nodes[2][2].pieces:print()
	--self.board.nodes[2][4].pieces:print()
	--for i,v in ipairs(self.pieces.sheeps) do
	--	print(v.name.." "..v.r.." "..v.c)
--		if v.r<0 then
--			break
--		end
--	end
	self:AddPieceToBoard(3, 2, 25, true)
	self:AddPieceToBoard(3, 4, 26, true)

	self.turn = PIECETYPE.tigger
	self.curpick = -1
end

function Game:init()
	self.board:Init()
	self.pieces:init(2, 24)
	self:restart()
end

--1:25 2:26--
function Game:getsheepmoveablenodeidx(idx)
	local curpiece = self.pieces:getpiece(idx)
	local curnode = self.board.nodes[curpiece.r][curpiece.c]
	local lidx = 0
	local nidx = 0
	local line = nil
	local tr = 0
	local tc = 0
	local tn = nil
	res = {}
	for i=1, #curnode.lines do
		lidx = curnode.lines[i].line
		nidx = curnode.lines[i].idx
		line = self.board.lines[lidx]
		if nidx - 1 > 0 then
			tr = indexToRow(line.nodes[nidx - 1])
			tc = indexToCol(line.nodes[nidx - 1])
			tn = self.board.nodes[tr][tc]
			if tn:empty() or (tn:canaddpiece() and self.pieces:getpiece(tn:firstpiece()).type == PIECETYPE.sheep) then
				res[#res + 1] = line.nodes[nidx - 1]
			end
		end
		if nidx + 1 <= #line.nodes then
			tr = indexToRow(line.nodes[nidx + 1])
			tc = indexToCol(line.nodes[nidx + 1])
			tn = self.board.nodes[tr][tc]
			if tn:empty() or (tn:canaddpiece() and self.pieces:getpiece(tn:firstpiece()).type == PIECETYPE.sheep) then
				res[#res + 1] = line.nodes[nidx + 1]
			end
		end
	end
	return res
end

function Game:gettiggermoveablenodeidx(idx)
	local idx = idx + 24
	local curpiece = self.pieces:getpiece(idx)
	local curnode = self.board.nodes[curpiece.r][curpiece.c]
	local lidx = 0
	local nidx = 0
	local line = nil
	local tr = 0
	local tc = 0
	local tn = nil
	res = {}
	for i=1, #curnode.lines do
		lidx = curnode.lines[i].line
		nidx = curnode.lines[i].idx
		line = self.board.lines[lidx]


		--ss = "Line index: " .. lidx.."nIdx: "..curnode.lines[i].idx
		--print(ss)

		--ss = ""
		--for i=1, #line.nodes do
		--	ss = ss.." "..line.nodes[i]
		--end
		--print(ss)

		if nidx - 1 > 0 then
			tr = indexToRow(line.nodes[nidx - 1])
			tc = indexToCol(line.nodes[nidx - 1])
			tn = self.board.nodes[tr][tc]
			if tn:empty() then
				res[#res + 1] = line.nodes[nidx - 1]
			elseif nidx - 2 > 0 and self.pieces:getpiece(tn:firstpiece()).type == PIECETYPE.sheep then
				tr = indexToRow(line.nodes[nidx - 2])
				tc = indexToCol(line.nodes[nidx - 2])
				tn = self.board.nodes[tr][tc]
				if tn:empty() then
					res[#res + 1] = line.nodes[nidx - 2]	
				end
			end
		end
		if nidx + 1 <= #line.nodes then
			tr = indexToRow(line.nodes[nidx + 1])
			tc = indexToCol(line.nodes[nidx + 1])
			--print("tr "..tr.."tc: "..tc)
			tn = self.board.nodes[tr][tc]
			if tn:empty() then
				res[#res + 1] = line.nodes[nidx + 1]
			elseif nidx + 2 <= #line.nodes and self.pieces:getpiece(tn:firstpiece()).type == PIECETYPE.sheep then
				tr = indexToRow(line.nodes[nidx + 2])
				tc = indexToCol(line.nodes[nidx + 2])
				tn = self.board.nodes[tr][tc]
				if tn:empty() then
					res[#res + 1] = line.nodes[nidx + 2]	
				end
			end
		end
	end
	return res
end

function Game:istiggerunmoveable(idx)
	res = self:gettiggermoveablenodeidx(idx)
	return #res == 0
end

function Game:pickpiece(idx)
	if self.turn == PIECETYPE.tigger then
		if idx< 25 or idx>26 then
			self.curpick = -1;
			return false
		else
			self.curpick = idx
			return true
		end
	else 
		if idx<1 or idx>24 then
			self.curpick = -1;
			return false
		else
			self.curpick = idx
			return true
		end
	end
end

function Game:movepieceto(r, c, pieceIdx)
	curPiece = self.pieces:getpiece(pieceIdx)
	self.board.nodes[curPiece.r][curPiece.c].pieces:remove_item(pieceIdx)
	self.board.nodes[r][c].pieces:push_back(pieceIdx)
	curPiece.r = r
	curPiece.c = c
	if curPiece.type == PIECETYPE.sheep then
		self.turn = PIECETYPE.tigger
	else
		self.turn = PIECETYPE.sheep
	end
	--print("It's turn to "..self.turn)

end

function Game:eatsheepinnode(node)
	idx = node.pieces:pop_back()
	self.pieces:getpiece(idx).dead = true
end

function Game:moveto(r, c)
	if self.curpick < 1 or self.curpick > 26 or r < 1 or r > 5 
		or c< 1 or c > 5 then
		print("curpick or r, c error")
		return false
	end

	local curPiece = self.pieces:getpiece(self.curpick)
	local curNode = self.board.nodes[curPiece.r][curPiece.c]
	local tarNode = self.board.nodes[r][c]
	local lidx = curNode:getline(tarNode)
	local midNode

	--not same line
	if not lidx then
		print("Can't get line")
		return false
	end

	local curidx = curNode:getidxofline(lidx)
	local taridx = tarNode:getidxofline(lidx)

	print("Line: "..lidx.." Move from: "..curidx.." To: "..taridx)

	if curidx == taridx or not curidx or not taridx then
		return false
	end

	local step = math.abs(curidx - taridx)
	if  step == 1 then
		--Move one step, move if target node can hold--
		if curPiece.type == PIECETYPE.tigger then
			if tarNode:empty() then
				print("Tigger move one step")
				self:movepieceto(r, c, self.curpick)
			else
				print("Target node is not empty")
			end

		else
			if tarNode:canaddpiece() and 
				(not tarNode:firstpiece() or self.pieces:getpiece(tarNode:firstpiece()).type == curPiece.type) then
				print("Sheep move one step")
				self:movepieceto(r, c, self.curpick)
			else
				print("Can't move to target")
			end
		end
	elseif step == 2 and curPiece.type == PIECETYPE.tigger and tarNode:empty() then
		mididx = (curidx + taridx)/2
		midNode = self.board.nodes[indexToRow(self.board.lines[lidx].nodes[mididx])][indexToCol(self.board.lines[lidx].nodes[mididx])]
		if midNode:firstpiece() and self.pieces:getpiece(midNode:firstpiece()).type == PIECETYPE.sheep then
			print("Trigger move and eat sheep in node "..mididx)
			self:movepieceto(r, c, self.curpick)
			self:eatsheepinnode(midNode)
		else
			print("Trigger can't jump");
		end
	end
	return false
end


function Game:getpiecesonnode(r, c)
	local res = {}
	--print(r.." "..c.." ")
	--print(self.board.nodes[r][c])
	for i=1, self.board.nodes[r][c].pieces:count() do
		res[#res+1] = self.board.nodes[r][c].pieces:getAt(i)
	end
	return res
end


function Game:whowin()
	if self.turn == PIECETYPE.tigger then
		if self:istiggerunmoveable(1) and self:istiggerunmoveable(2) then
			return PIECETYPE.sheep
		end
	else
		local bres = true
		for i=1,24 do
			if not self.pieces.sheeps[i].dead then
				bres = false
				break
			end
		end
		if bres then
			return PIECETYPE.tigger
		end
	end
	return nil 
end

--no sheeps or tigger can't move
function Game:isover()
	type = self:whowin()
	if type then
		return true
	else
		return false
	end
end

game.lua

#!
dofile("board.lua")

function getnodestr(game, node)
	if node.pieces:count() > 0 then
		--print(game.pieces:getpiece(node.pieces:getAt(1)).name);
		if game.pieces:getpiece(node.pieces:getAt(1)).type == PIECETYPE.sheep then
			return node.pieces:count().."S"
		else
			return node.pieces:count().."T"
		end
	end
	return "0 "
end

function drawnodeonline(i, game, board)
	local str = ""
	for j=1,4 do
		str = str ..getnodestr(game, board.nodes[i][j]).." ----\t"
	end
		str = str .. getnodestr(game, board.nodes[i][5])	
	print(str)
end

function drawchessboard(game, board)
	drawnodeonline(1, game, board)
	print("|   \\   |    /  |   \\   |    /  |")
	print("|     \\ |  /    |     \\ |  /    |")

	drawnodeonline(2, game, board)
	print("|     / |  \\    |     / |  \\    |")
	print("|   /   |    \\  |   /   |    \\  |")

	drawnodeonline(3, game, board)
	print("|   \\   |    /  |   \\   |    /  |")
	print("|     \\ |  /    |     \\ |  /    |")

	drawnodeonline(4, game, board)
	print("|     / |  \\    |     / |  \\    |")
	print("|   /   |    \\  |   /   |    \\  |")
	drawnodeonline(5, game, board)
end

function printturn(g)
	if g.turn == 1 then
		print("It's turn to Tigger")
	else
		print("It's turn to Sheep")
	end
end

game = Game:new{}
game:init()
drawchessboard(game,game.board)
printturn(game)
winner = nil
while not winner do
	row = io.read("*number")
	col = io.read("*number")
	pics = game:getpiecesonnode(row, col)
	local str = " "
	if #pics > 1 then
		print("Select piece: ")
		for i=1, #pics do
			str = str..pics[i].."  "
		end
		print(str)
		sel = io.read("*number")
		bok = false
		for i=1,#pics do
			if sel == pics[i] then
				bok = true;
				break
			end
		end
		if bok and game:pickpiece(sel) then
			print("Input move target")
			row = io.read("*number")
			col = io.read("*number")
			game:moveto(row, col)
		else
			print("Wrong")
		end
	elseif #pics == 1 then
		if game:pickpiece(pics[1]) then
			print("Select piece "..pics[1])
			print("Input move target")
			row = io.read("*number")
			col = io.read("*number")
			game:moveto(row, col)
		else
			print("Wrong piece")
		end
	else
		print("No piece available")
	end
	drawchessboard(game,game.board)
	printturn(game)
	
	winner = game:whowin()
end
if winner == PIECETYPE.tigger then
	print("Tigger win")
else
	print("Sheep win")
end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值