Kampf um Resourcen. Programmieren von Gewusel: Unterschied zwischen den Versionen

aus dem Wiki des Entropia e.V., CCC Karlsruhe
Keine Bearbeitungszusammenfassung
 
Keine Bearbeitungszusammenfassung
 
(19 dazwischenliegende Versionen von 11 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
Hier ein kleines Beispielscript:
[[Datei:Infon.jpg|right]]
 
== Sourcecode ==
 
Ich habe auf http://infon.dividuum.de eine vorerst minimale Seite zum Spiel eingerichtet. Dort gibt es den Sourcecode.
 
Wenn ihr das Spiel irgendwo laufen lasst, waere es super, wenn ihr Bilder davon an mich (Email Adresse siehe obige Seite) schickt/bei flickr postet.
 
== Feature Requests ==
 
* Möglichkeit für *alle* spieler, sich die Punkte anzeigen zu lassen (evtl. per Kommando "p" an der Konsole?)
** Erm, "p" ist ja schon part game. Wie waers mit "s" (wie stats)? ''--codec''
*** Ich baue das bei der naechsten Iteration ein ''--dividuum''
* mehr farben
** done. sind jetzt 16 unterschiedliche ''--dividuum''
* laengere kaempfe?
** done. nur noch halbe hitpoints bei kaempfen ''--dividuum''
* fuettern schneller als essen ''--kcarccmkcaj''
* mehr essen?
* mehr bass!
* blackjack und nutten!
* kein selbstmord
** doch. wird aber haerter bestraft.
* server sourcen irgendwo schon zu haben ?
** jetzt schon
 
== Beispiel-Scripte ==
 
===Blueloop V00===
 
<pre>
--------------------------------------------------------------------------
-- Blueloop V00
--
-- Fuer jedes gespawnte Vieh wird eine eigene Creature Klasse instanziiert
--------------------------------------------------------------------------
 
function Creature:onSpawned()
print("Creature " .. self.id .. " spawned")
end
function Creature:onAttacked(attacker)
print("Help! Creature " .. self.id .. " is attacked by Creature " .. attacker)
end
function Creature:onKilled(killer)
if killer == self.id then
print("Creature " .. self.id .. " suicided")
elseif killer then
print("Creature " .. self.id .. " killed by Creature " .. killer)
else
print("Creature " .. self.id .. " died")
end
end
function Wait()
while (get_state(self.id) ~= CREATURE_IDLE) do
self:wait_for_next_round()
end;
end
function Creature:main()
if self.dx == nil then self.dx = 256 end
if self.dy == nil then self.dy = 0 end
if victim  == nil then victim  = -1 end
---------------------------------------------- Wenn ein globaler Angriff aktiv ist:
if (victim ~= -1) and (get_type(self.id) == 1) then
if exists(victim) then
local x,y = get_pos(victim)                    -- Wo ist der angegriffene?
self:moveto(x,y)                              -- hinlaufen
self:attack(victim)                            -- angreifen!
else
victim = -1                                    -- Tot -> Angriff beenden
print"Angriff beendet!"
end
end
---------------------------------------------- Warten bis Creatur IDLE
if get_state(self.id) ~= CREATURE_IDLE  then
self:wait_for_next_round()
return
end
---------------------------------------------- Wo ist der nächste Feind?
local feind_id, feind_x, feind_y, feind_playernum, feind_dist = nearest_enemy(self.id)
---------------------------------------------- Wenn er nah genug ist und wir gesund sind -> angreifen
if (feind_id ~= nil) and (victim == -1) then
if (feind_dist < 8000) and (self:health() > 50) and (victim == -1) then
print("Starte Angriff auf " .. feind_id )
victim = feind_id
end
end
---------------------------------------------- Fressen!
if get_tile_food(self.id) > 0 then 
set_state(self.id, CREATURE_EAT)
else
local x, y = self:pos()
if not self:moveto(x+self.dx,y+self.dy) then
self.dx = math.random(512)-256
self.dy = math.random(512)-256
end
end
if self:health() < 90 then
set_state(self.id, CREATURE_HEAL)
end;
if get_food(self.id) > 8000 then
if get_type(self.id) == 0 then
set_convert(self.id, 1)
set_state(self.id,CREATURE_CONVERT)
else
set_state(self.id,CREATURE_SPAWN)
end
end
if get_state(self.id) == CREATURE_IDLE then
self:moveto(get_koth_pos())
end
self:wait_for_next_round()
end
---------------------------------------------------------------------------------
 
</pre>
 
===Blueloop V01===
 
<pre>


--------------------------------------------------------------------------
--------------------------------------------------------------------------
-- Blueloop V00
-- Default Logik
--
--
-- Fuer jedes gespawnte Vieh wird eine eigene Creature Klasse instanziiert
-- Fuer jedes gespawnte Vieh wird eine eigene Creature Klasse instanziiert
Zeile 13: Zeile 150:
function Creature:onAttacked(attacker)
function Creature:onAttacked(attacker)
     print("Help! Creature " .. self.id .. " is attacked by Creature " .. attacker)
     print("Help! Creature " .. self.id .. " is attacked by Creature " .. attacker)
-- Ich bin noch zu klein zum kämpfen
if (get_type(self.id) == 0) or (self:health() > 20) then
local x,y = self:pos()
                                -- weglaufen
self:set_path(x-16000+math.random(8000),y-1600+math.random(8000))
self:begin_walk_path()
else -- Smack my Bit up!
self:set_target(attacker)
self:begin_attacking()
end
end
end


Zeile 25: Zeile 173:
end
end


function Wait()
function Creature:Wait()
while (get_state(self.id) ~= CREATURE_IDLE) do
while (get_state(self.id) ~= CREATURE_IDLE) do
self:wait_for_next_round()
self:wait_for_next_round()
Zeile 31: Zeile 179:
end
end


function Creature:main()
function Creature:Fressen()
if self.dx == nil then self.dx = 256 end
if get_tile_food(self.id) > 0 then   
if self.dy == nil then self.dy = 0 end
set_state(self.id, CREATURE_EAT)
if victim  == nil then victim = -1 end
self:Wait()
else
---------------------------------------------- Wenn ein globaler Angriff aktiv ist:
local x, y = self:pos()
if (victim ~= -1) and (get_type(self.id) == 1) then
if not self:moveto(x+self.dx,y+self.dy) then
if exists(victim) then
 
self.dx = math.random(256)-128
local x,y = get_pos(victim)                   -- Wo ist der angegriffene?
self.dy = math.random(256)-128
self:moveto(x,y)                               -- hinlaufen
self:attack(victim)                           -- angreifen!
else
victim = -1                                    -- Tot -> Angriff beenden
print"Angriff beendet!"
end
end
end
end
if self:health() < 90 then
set_state(self.id, CREATURE_HEAL)
self:Wait()
end
end


---------------------------------------------- Warten bis Creatur IDLE
function Creature:Angreifen()
if get_state(self.id) ~= CREATURE_IDLE  then
-- Wo ist der nächste Feind?
self:wait_for_next_round()
return
end
---------------------------------------------- Wo ist der nächste Feind?
local feind_id, feind_x, feind_y, feind_playernum, feind_dist = nearest_enemy(self.id)
local feind_id, feind_x, feind_y, feind_playernum, feind_dist = nearest_enemy(self.id)
---------------------------------------------- Wenn er nah genug ist und wir gesund sind -> angreifen
-- Wenn er nah genug ist und wir gesund sind -> angreifen
if (feind_id ~= nil) and (victim == -1) then
if (feind_id ~= nil) and (feind_dist < 500) and (self:health() > 60) then
if (feind_dist < 8000) and (self:health() > 50) and (victim == -1) then
print("Starte Angriff auf " .. feind_id .. " Abstand: " .. feind_dist)
print("Starte Angriff auf " .. feind_id )
 
victim = feind_id
while (exists(feind_id)) do
local x,y = get_pos(feind_id)                  -- Wo ist der angegriffene?
self:moveto(x,y)                              -- hinlaufen
self:attack(feind_id)                          -- angreifen!
self:Wait()
end
end
end
end
end


    ---------------------------------------------- Fressen!
function Creature:main()
if self.dx == nil then self.dx = 256 end
if self.dy == nil then self.dy = 0 end
if victim  == nil then victim  = -1 end
if get_tile_food(self.id) > 0 then
if get_type(self.id) == 0 then
set_state(self.id, CREATURE_EAT)
print("Creature " .. self.id .. " soll fressen")
while get_food(self.id) < 8000 do
self:Fressen()
end
print("Creature " .. self.id .. " soll sich verwandeln")
set_convert(self.id, 1)
set_state(self.id,CREATURE_CONVERT)
self:Wait()
else
else
local x, y = self:pos()
print("Creature " .. self.id .. " soll fressen")
if not self:moveto(x+self.dx,y+self.dy) then
while get_food(self.id) < 8000 do
self.dx = math.random(512)-256
self:Fressen()
self.dy = math.random(512)-256
self:Angreifen()
end
end
end
print("Creature " .. self.id .. " vermehrt sich")
set_state(self.id,CREATURE_SPAWN)
self:Wait()
if self:health() < 90 then
--print("Creature " .. self.id .. " soll zu King of the Hill")
set_state(self.id, CREATURE_HEAL)
end;
if get_food(self.id) > 8000 then
--self:moveto(get_koth_pos())
    if get_type(self.id) == 0 then
--self:Wait()
set_convert(self.id, 1)
--print("Creature " .. self.id .. " ist King of the Hill")
set_state(self.id,CREATURE_CONVERT)
--while self:health() > 30 do
else
-- local feind_id, feind_x, feind_y, feind_playernum, feind_dist = nearest_enemy(self.id)
set_state(self.id,CREATURE_SPAWN)
-- self:attack(feind_id)  
end
--end
end
end
if get_state(self.id) == CREATURE_IDLE then
self:moveto(get_koth_pos())
end
self:wait_for_next_round()
end
end


--------------------------------------------------------------------------
</pre>
 
===Updater===
 
<pre>
require 'socket'
require 'timeout'
 
class GameConn
  def initialize
    @sock = TCPSocket.new('23.42.2.254', 1234)
 
    while buf = read_with_timeout
      if buf =~ /Press \<enter\>/
        @sock.puts
      elsif buf =~ /enter '\?' for help/
        @sock.puts 'j'
      elsif buf =~ /enter \<playernum\> or press enter for new player: /
        return
      end
    end
  end
 
  def join_already(num, password)
    @sock.puts(num)
    while buf = read_with_timeout
      if buf =~ /password for player \d+: /
        @sock.puts(password)
      elsif buf =~ /joined\. /
        return
      elsif buf =~/could not attach to player/
        raise buf
      end
    end
  end
 
  def join_new(password)
    @sock.puts
    while buf = read_with_timeout
      if buf =~ /password for new player: /
        @sock.puts(password)
      elsif buf =~ /joined\. /
        puts buf
        return
      end
    end
  end
 
  def name=(n)
    @sock.puts 'n'
    while buf = read_with_timeout
      if buf =~ /Player Name: /
        @sock.puts n
      elsif buf =~ /\> /
        return
      elsif buf =~ /cannot set name/
        raise buf
      end
    end
  end
 
  def read_with_timeout
    buf = ''
    while buf.size == 0
      begin
        Timeout::timeout(0.1) {
          buf += @sock.read(1) while true
        }
      rescue Timeout::Error
      end
    end
    buf
  end
 
  def debug_loop!
    while buf = read_with_timeout
      print buf
    end
  end
 
  def batch(source)
    @sock.puts 'b'
    while buf = read_with_timeout
      if buf =~ /enter your lua code/
        @sock.puts source + "\n."
      elsif buf =~ /\> /
        return
      end
    end
  end
end
 
g = GameConn.new
if true  # Bei Bedarf zu false ändern
  g.join_already(6, '123')
else
  g.join_new('123')
end
g.name = 'CoolBot'
g.batch(IO::readlines('coolbot.lua').to_s)
g.debug_loop!
</pre>
 
=== Update Makefile ===
 
<pre>
PASS=XXX
PLAYERNO=XXX
IP=23.42.2.254
 
all:
        (echo ; echo j; echo ${PLAYERNO}; echo ${PASS}; echo b; cat bot.lua; echo ; echo .; echo r; echo q) | netcat ${IP} 1234
 
 
</pre>
 
[[Kategorie:GPN]]
[[Kategorie:GPN5]]
[[Kategorie:Spiele]]

Aktuelle Version vom 21. Juli 2017, 21:53 Uhr

Infon.jpg

Sourcecode

Ich habe auf http://infon.dividuum.de eine vorerst minimale Seite zum Spiel eingerichtet. Dort gibt es den Sourcecode.

Wenn ihr das Spiel irgendwo laufen lasst, waere es super, wenn ihr Bilder davon an mich (Email Adresse siehe obige Seite) schickt/bei flickr postet.

Feature Requests

  • Möglichkeit für *alle* spieler, sich die Punkte anzeigen zu lassen (evtl. per Kommando "p" an der Konsole?)
    • Erm, "p" ist ja schon part game. Wie waers mit "s" (wie stats)? --codec
      • Ich baue das bei der naechsten Iteration ein --dividuum
  • mehr farben
    • done. sind jetzt 16 unterschiedliche --dividuum
  • laengere kaempfe?
    • done. nur noch halbe hitpoints bei kaempfen --dividuum
  • fuettern schneller als essen --kcarccmkcaj
  • mehr essen?
  • mehr bass!
  • blackjack und nutten!
  • kein selbstmord
    • doch. wird aber haerter bestraft.
  • server sourcen irgendwo schon zu haben ?
    • jetzt schon

Beispiel-Scripte

Blueloop V00

 --------------------------------------------------------------------------
 -- Blueloop V00 
 --
 -- Fuer jedes gespawnte Vieh wird eine eigene Creature Klasse instanziiert
 --------------------------------------------------------------------------

	function Creature:onSpawned()
		print("Creature " .. self.id .. " spawned")
	end
	
	function Creature:onAttacked(attacker)
		print("Help! Creature " .. self.id .. " is attacked by Creature " .. attacker)
	end
	
	function Creature:onKilled(killer)
		if killer == self.id then
			print("Creature " .. self.id .. " suicided")
		elseif killer then 
			print("Creature " .. self.id .. " killed by Creature " .. killer)
		else
			print("Creature " .. self.id .. " died")
		end
	end
	
	function Wait()
		while (get_state(self.id) ~= CREATURE_IDLE) do
			self:wait_for_next_round()	
		end;
	end
	
	function Creature:main()
		if self.dx == nil then self.dx = 256 end
		if self.dy == nil then self.dy = 0 end
		if victim  == nil then victim  = -1 end
		
		---------------------------------------------- Wenn ein globaler Angriff aktiv ist:
		if (victim ~= -1) and (get_type(self.id) == 1) then
			if exists(victim) then
			
				local x,y = get_pos(victim)                    -- Wo ist der angegriffene?
				self:moveto(x,y)                               -- hinlaufen
				self:attack(victim)                            -- angreifen!
			else
				victim = -1                                    -- Tot -> Angriff beenden
				print"Angriff beendet!"
			end
		end
		
	
		---------------------------------------------- Warten bis Creatur IDLE
		if get_state(self.id) ~= CREATURE_IDLE  then
			self:wait_for_next_round()
			return
		end
		
		---------------------------------------------- Wo ist der nächste Feind?
		local feind_id, feind_x, feind_y, feind_playernum, feind_dist = nearest_enemy(self.id)	
		
		---------------------------------------------- Wenn er nah genug ist und wir gesund sind -> angreifen
		
		if (feind_id ~= nil) and (victim == -1) then
			if (feind_dist < 8000) and (self:health() > 50) and (victim == -1) then
				print("Starte Angriff auf " .. feind_id )
				victim = feind_id
			end
		end
	
		---------------------------------------------- Fressen!
		
		if get_tile_food(self.id) > 0 then  
			set_state(self.id, CREATURE_EAT)
		else
			local x, y = self:pos()
			if not self:moveto(x+self.dx,y+self.dy) then
				self.dx = math.random(512)-256
				self.dy = math.random(512)-256
			end
		end
		
		
		if self:health() < 90 then 
			set_state(self.id, CREATURE_HEAL)
		end;
			
		if get_food(self.id) > 8000 then
			if get_type(self.id) == 0 then
				set_convert(self.id, 1)
				set_state(self.id,CREATURE_CONVERT)
			else
				set_state(self.id,CREATURE_SPAWN)
			end
		end
		
		if get_state(self.id) == CREATURE_IDLE then
			self:moveto(get_koth_pos())
		end
		
		self:wait_for_next_round()
	end
	
 ---------------------------------------------------------------------------------

Blueloop V01


--------------------------------------------------------------------------
-- Default Logik 
--
-- Fuer jedes gespawnte Vieh wird eine eigene Creature Klasse instanziiert
--------------------------------------------------------------------------

function Creature:onSpawned()
    print("Creature " .. self.id .. " spawned")
end

function Creature:onAttacked(attacker)
    print("Help! Creature " .. self.id .. " is attacked by Creature " .. attacker)
	
										-- Ich bin noch zu klein zum kämpfen
	if (get_type(self.id) == 0) or (self:health() > 20) then
		local x,y = self:pos()
		                                 -- weglaufen
		self:set_path(x-16000+math.random(8000),y-1600+math.random(8000)) 
		self:begin_walk_path()
	else								 -- Smack my Bit up!
		self:set_target(attacker)
		self:begin_attacking()		
	end
end

function Creature:onKilled(killer)
    if killer == self.id then
        print("Creature " .. self.id .. " suicided")
    elseif killer then 
        print("Creature " .. self.id .. " killed by Creature " .. killer)
    else
        print("Creature " .. self.id .. " died")
    end
end

function Creature:Wait()
	while (get_state(self.id) ~= CREATURE_IDLE) do
		self:wait_for_next_round()	
	end;
end

function Creature:Fressen()
	if get_tile_food(self.id) > 0 then  
		set_state(self.id, CREATURE_EAT)
		self:Wait()
	else
		local x, y = self:pos()
		if not self:moveto(x+self.dx,y+self.dy) then

			self.dx = math.random(256)-128
			self.dy = math.random(256)-128
			
			
		end
	end
	
	if self:health() < 90 then
		set_state(self.id, CREATURE_HEAL)
		self:Wait()
	end
end

function Creature:Angreifen()
	-- Wo ist der nächste Feind?
	local feind_id, feind_x, feind_y, feind_playernum, feind_dist = nearest_enemy(self.id)	
	
	-- Wenn er nah genug ist und wir gesund sind -> angreifen
	
	if (feind_id ~= nil) and (feind_dist < 500) and (self:health() > 60) then
		print("Starte Angriff auf " .. feind_id .. " Abstand: " .. feind_dist)

		while (exists(feind_id)) do
			local x,y = get_pos(feind_id)                  -- Wo ist der angegriffene?
			self:moveto(x,y)                               -- hinlaufen
			self:attack(feind_id)                          -- angreifen!
			self:Wait()
		end
	end
	
end

function Creature:main()
	if self.dx == nil then self.dx = 256 end
	if self.dy == nil then self.dy = 0 end
	if victim  == nil then victim  = -1 end
	
	if get_type(self.id) == 0 then
		print("Creature " .. self.id .. " soll fressen")
		while get_food(self.id) < 8000 do
			self:Fressen()
		end
		print("Creature " .. self.id .. " soll sich verwandeln")
		set_convert(self.id, 1)
		set_state(self.id,CREATURE_CONVERT)
		self:Wait()
	else
		print("Creature " .. self.id .. " soll fressen")
		while get_food(self.id) < 8000 do
			self:Fressen()
			self:Angreifen()
		end
		print("Creature " .. self.id .. " vermehrt sich")
		set_state(self.id,CREATURE_SPAWN)
		self:Wait()
		--print("Creature " .. self.id .. " soll zu King of the Hill")
		
		--self:moveto(get_koth_pos())
		--self:Wait()
		--print("Creature " .. self.id .. " ist King of the Hill")
		--while self:health() > 30 do
		--	local feind_id, feind_x, feind_y, feind_playernum, feind_dist = nearest_enemy(self.id)			
		--	self:attack(feind_id) 
		--end
	end
end

Updater

require 'socket'
require 'timeout'

class GameConn
  def initialize
    @sock = TCPSocket.new('23.42.2.254', 1234)

    while buf = read_with_timeout
      if buf =~ /Press \<enter\>/
        @sock.puts
      elsif buf =~ /enter '\?' for help/
        @sock.puts 'j'
      elsif buf =~ /enter \<playernum\> or press enter for new player: /
        return
      end
    end
  end

  def join_already(num, password)
    @sock.puts(num)
    while buf = read_with_timeout
      if buf =~ /password for player \d+: /
        @sock.puts(password)
      elsif buf =~ /joined\. /
        return
      elsif buf =~/could not attach to player/
        raise buf
      end
    end
  end

  def join_new(password)
    @sock.puts
    while buf = read_with_timeout
      if buf =~ /password for new player: /
        @sock.puts(password)
      elsif buf =~ /joined\. /
        puts buf
        return
      end
    end
  end

  def name=(n)
    @sock.puts 'n'
    while buf = read_with_timeout
      if buf =~ /Player Name: /
        @sock.puts n
      elsif buf =~ /\> /
        return
      elsif buf =~ /cannot set name/
        raise buf
      end
    end
  end

  def read_with_timeout
    buf = ''
    while buf.size == 0
      begin
        Timeout::timeout(0.1) {
          buf += @sock.read(1) while true
        }
      rescue Timeout::Error
      end
    end
    buf
  end

  def debug_loop!
    while buf = read_with_timeout
      print buf
    end
  end

  def batch(source)
    @sock.puts 'b'
    while buf = read_with_timeout
      if buf =~ /enter your lua code/
        @sock.puts source + "\n."
      elsif buf =~ /\> /
        return
      end
    end
  end
end

g = GameConn.new
if true  # Bei Bedarf zu false ändern
  g.join_already(6, '123')
else
  g.join_new('123')
end
g.name = 'CoolBot'
g.batch(IO::readlines('coolbot.lua').to_s)
g.debug_loop!

Update Makefile

PASS=XXX
PLAYERNO=XXX
IP=23.42.2.254

all:
        (echo ; echo j; echo ${PLAYERNO}; echo ${PASS}; echo b; cat bot.lua; echo ; echo .; echo r; echo q) | netcat ${IP} 1234