Skip to content

Apoema's intermediate code

Caio edited this page Jun 15, 2013 · 2 revisions
class Player
	def initialize
		@lados = [:forward, :backward, :right, :left]
		$mapa = Hash.new
		@posicaoatual = [0,0]
		@redor = Redor.new()
		@bombas = 0
		@distbomba = 0
	end

	def play_turn(warrior)
		@heroi = warrior

		if $mapa.empty? || @andou
			mapear()
			@andou = false
		end

		objetivo()
		@redor.sentir(@posicaoatual)

		puts "Temos #{@redor.inimigos} pela frente, o mais perigoso é #{@pelafrente} e nosso alvo é #{@objetivo}, nosso caminho é #{@direcao}. Explodi #{@bombas} bombas"

		#puts $mapa

		case @redor.inimigos
		when 0
			if @objetivo == "Escadas"
				andar(@direcao)
			elsif @redor.refens != nil
				@heroi.rescue!(@redor.refens)
				mapeara(@redor.refens, :nothing)
				@distbomba = @distbomba == 1 ? 0 : @distbomba
			elsif @bombear
				detonar(@direcao)
			elsif @level4
				andar(:backward)
				@level4 = false
			elsif @level6 && @direcao == :right
				andar(:backward)
			elsif @objetivo == "Thick Sludge"
				lutar_thick(:longe)
			elsif @objetivo == "Sludge"
				lutar_sludge(:longe)
			else
				andar(@direcao)
			end
		when 1
			possodevodesviar = (@distbomba > 0 && !(@heroi.feel(:left).to_s == "wall" && @heroi.feel(:right).to_s == "wall") && @redor.left != "preso")
			#possodevodesviar = @distbomba > 0 && @heroi.feel(:left).empty?

			if possodevodesviar
				if @pelafrente == "nothing"
					andar(@direcao)
				elsif @heroi.feel(:left).empty?
					andar(:left)
					@level6 = true
				elsif @heroi.feel(:forward).empty?
					andar(:forward)
				else
					puts "Isso não deveria estar acontecendo"
				end
			elsif @pelafrente == "Sludge"
				lutar_sludge
			elsif @pelafrente == "Thick Sludge"
				lutar_thick(:perto)
			elsif @redor.refens != nil
				@heroi.rescue!(@redor.refens)
				mapeara(@redor.refens, :nothing)
				@distbomba = @distbomba == 1 ? 0 : @distbomba
			elsif @bombear
				detonar(@direcao)
			else
				andar(@direcao)
			end
		when 2
			if @direcao == :left
				@heroi.bind!(:forward)
				mapeara(:forward, :preso)
			else
				@heroi.bind!(:left)
				mapeara(:left, :preso)
			end
		when 3
			if !@redor.refens.nil?
				@heroi.rescue!(@redor.refens)
				mapeara(@redor.refens, :nothing)
				@distbomba = @distbomba == 1 ? 0 : @distbomba
			elsif !@redor.nada.nil?
				andar(@redor.nada)
			else
				@heroi.bind!(:right)
				mapeara(:right, :preso)
			end
		end
	end

	def objetivo()
		@objetivo = @heroi.listen()[0].nil? ? "Escadas" : @heroi.listen()[0] 

		if @heroi.listen().to_s == "[Captive, Captive, Sludge, Thick Sludge, Sludge]"
			@level4 = true
		end

		contarbombar = 0
		bombardear = [0,0]
		@heroi.listen().each do |espaco|
			if espaco.ticking? 
				@distbomba = @heroi.distance_of(espaco)
				if @distbomba - 3 < @heroi.distance_of(@objetivo)
					@objetivo = espaco
				end
			elsif @heroi.distance_of(espaco) == @heroi.distance_of(@objetivo) && @distbomba == 0
				if espaco.to_s == "Sludge" && @objetivo.to_s == "Captive"
					@objetivo = espaco
				end
			elsif @heroi.distance_of(espaco) < @heroi.distance_of(@objetivo) && (@heroi.distance_of(espaco) < @distbomba - 3 || @distbomba == 0)
				@objetivo = espaco
			end
			if @heroi.distance_of(espaco) == 2 && (espaco.to_s == "Sludge" || espaco.to_s == "Thick Sludge")
				contarbombar += 1
				bombardear = bombardear.somarvetor(dirmapa(@heroi.direction_of(espaco)))
			end
		end

		if @objetivo == "Escadas"
			@direcao = @heroi.direction_of_stairs
		elsif @heroi.distance_of(@objetivo) == 1
			@direcao = @redor.alvo
		else
			@direcao = @heroi.direction_of(@objetivo)
		end

		if bombear
			@bombear = true
			@direcao = :backward
		elsif contarbombar > 1
			@bombear = true
			@direcao = mapdir(bombardear)
		end

		@objetivo = @objetivo.to_s
		@pelafrente = $mapa[posicao(@direcao)].to_s
	end

	def mapear()
		@lados.each do |lado|
			posicao = @posicaoatual
			for i in 0..2
				posicao = posicao.somarvetor(dirmapa(lado))
				$mapa[posicao] = $mapa[posicao].nil? ? @heroi.look(lado)[i] : $mapa[posicao]
				$mapa[posicao + [:vida]] = $mapa[posicao + [:vida]].nil? ? 0 : $mapa[posicao + [:vida]]

				case @heroi.look(lado)[i].to_s
				when "Sludge"
					$mapa[posicao + [:vida]] += $mapa[posicao + [:vida]] < 1 ? 12 : 0
				when "Thick Sludge"
					$mapa[posicao + [:vida]] += $mapa[posicao + [:vida]] < 1 ? 24 : 0
				end
			end
		end
		@redor.sentir(@posicaoatual)
	end

	def mapeara(lado, oque)
		posicao = posicao(lado)
		$mapa[posicao] = oque
		@redor.sentir(@posicaoatual)
	end

	def bombear
		posicao = posicao(:backward)

		contador = 0
		@lados.each do |lado|
			posicao2 = posicao.somarvetor(dirmapa(lado))
			if $mapa[posicao2] == :preso && $mapa[posicao2 + [:vida]] > 0
				contador += 1
			end
		end

		if contador > 1
			true
		else
			false
		end
	end

	def andar(lado)
		if $mapa[posicao(lado)] != :nothing && $mapa[posicao(lado)] != :preso && $mapa[posicao(lado)].stairs? && @objetivo != "Escadas"
			@heroi.walk!(:left)
			@posicaoatual = posicao(:left)
		else
			@heroi.walk!(lado)
			@posicaoatual = posicao(lado)
		end
		@andou = true
	end

	def detonar(lado=:forward)
		if @heroi.health < 5
			@heroi.rest!
		else
			@heroi.detonate!(lado)
			@bombas += 1

			if @bombas == 3
				@bombear = false
				@bombas = 0
			end

			posicao = posicao(lado)
			$mapa[posicao + [:vida]] -= 8
			@lados.each do |lado|
				if posicao.somarvetor(dirmapa(lado)) != @posicaoatual
					if $mapa[posicao.somarvetor(dirmapa(lado)) + [:vida]].nil? 
						$mapa[posicao.somarvetor(dirmapa(lado)) + [:vida]] = -4
					else 
						$mapa[posicao.somarvetor(dirmapa(lado)) + [:vida]] -= 4
					end
				end
			end	
		end

	end

	def lutar_thick(distancia)
		posicao = posicao(@direcao)
		while $mapa[posicao].to_s == "nothing"
			posicao = posicao.somarvetor(dirmapa(@direcao))
		end

		vida = $mapa[posicao + [:vida]]
		if vida.nil?
			vida = 24
		elsif vida < 0
			vida += 24
		end

		case distancia
		when :longe
			if @heroi.health < 7
				@heroi.rest!
			elsif vida > 12 && @heroi.health < 15
				@heroi.rest!
			else
				andar(@direcao)
			end
		when :perto
			if vida < 6
				@heroi.attack!(@direcao)
			elsif vida < 9
				detonar(@direcao)
			elsif vida < 11
				@heroi.attack!(@direcao)
			else
				detonar(@direcao)
			end
		end
	end

	def lutar_sludge(distancia=:perto)
		posicao = posicao(@direcao)
		vida = $mapa[posicao + [:vida]]

		case distancia
		when :longe
			if @heroi.health < 7
				@heroi.rest!
			else
				andar(@direcao)
			end
		when :perto
			if @direcao == :backward
				detonar(:backward)
			else
				if vida < 6
					@heroi.attack!(@direcao)
				elsif vida < 9
					detonar(@direcao)
				elsif vida < 11
					@heroi.attack!(@direcao)
				else
					detonar(@direcao)
				end
			end
		end
	end

	def posicao(lado)
		@posicaoatual.somarvetor(dirmapa(lado))
	end

	def dirmapa(lado)
		case lado
		when :forward
			posicao = [1,0]
		when :backward
			posicao = [-1,0]
		when :left
			posicao = [0,1]
		when :right
			posicao = [0,-1]
		end

		posicao
	end

	def mapdir(posicao)
		if posicao[0] > 0
			lado = :forward
		elsif posicao[0] < 0
			lado = :backward
		elsif posicao[1] > 0
			lado = :left
		elsif posicao[1] < 0
			lado = :right
		end

		lado
	end
end

class Redor
	attr_accessor :forward, :backward, :left, :right

	def initialize
		@lados = [:forward, :backward, :right, :left]
	end

	def inimigos
		contador = 0
		@lados.map do |lado|
			contador += contador(lado, "Sludge", "Thick Sludge")
		end
		contador
	end

	def alvo
		ret = nil
		alvos = ["Captive", "preso", "Sludge", "Thick Sludge"]

		alvos.each do |alvo|
			if !achar(alvo).nil? then ret = achar(alvo) end
		end

		ret
	end

	def nada
		!achar("nothing").nil? ? achar("nothing") : nil
	end

	def refens
		!achar("Captive").nil? ? achar("Captive") : nil
	end

	def contador(lado, *oque)
		oque.include?(eval("@#{lado.to_s}")) ? 1 : 0
	end

	def achar(oque)
		ret = nil
		@lados.map do |lado|
			if oque.include?(eval("@#{lado.to_s}")) then ret = lado end
		end
		ret
	end

	def sentir(posicaoatual)
		@forward = $mapa[posicaoatual.somarvetor([1,0])].to_s
		@backward = $mapa[posicaoatual.somarvetor([-1,0])].to_s
		@left = $mapa[posicaoatual.somarvetor([0,1])].to_s
		@right = $mapa[posicaoatual.somarvetor([0,-1])].to_s
	end
end

class Array
	def somarvetor(v1)
		[self,v1].transpose.map {|x| x.reduce(:+)}	
	end
end