SeedRnd MilliSecs()
GameTime = CreateTimer(60)
Const MaxTasks =100
; States & Action :
Const DEL= 0 , STAY=1 ,GO=2 ,WORK=3 ,ATACK=4 ,DIE=5 ,GOBACK = 6,random=7 , pause =8 ,speed = 9 ,randomTree =10 , moveto =11
Global countBot ,countTasks, timer ,resource% , idTree
Global b.bot
Type bot
Field x#,y#,tx#,ty# , live
Field name$ , state$ ,speed#,speedbot#[MaxTasks], idAtackBot , idBot ,pulse
Field task[MaxTasks], oldTask[MaxTasks] ,nextTask, endTask ,urgentTask=False ; The task
Field cycle, ignoreCycle[MaxTasks] , timer[MaxTasks], timer2[MaxTasks] ; elements
Field endTree, idTree
End Type
Function addBot.bot(name$, cycle=False )
b.bot = New bot
; b\task[b\nextTask] = STAY
b\name$ = name$
b\live = 100
b\cycle = cycle
b\idBot = countBot
countBot = countBot+1
Return b
End Function
Function addTree.bot(name$ )
b.bot= New bot
b\name$ = name$
b\idTree = idTree
idTree = idTree +1
b\idBot = countBot
countBot = countBot+1
b\x = Rand(20,780) : b\y = Rand(20,580)
Return b
End Function
;= Task =
; addTask() - добавить задачу в конец очереди
; addUrgentTask() - добавить задачу в начало очереди
; addInstantTask() - добавить задачу, которая выполнится всего 1 раз в конец очереди
; addUrgentInstantTask() - добавить одноразовую задачу в начало очереди
; addPause() - добавить паузу в конец очереди (в кадрах)
; removeAllTasks() - удалить все задачи из очереди
Function addTask(b.bot, parametr=0,ignoreCycle=False)
If b\task[b\nextTask] = 0
b\task[b\nextTask] = parametr
b\ignoreCycle[b\nextTask] = ignoreCycle
b\endTask = b\nextTask
b\nextTask = b\nextTask+1
countTasks = countTasks+1
End If
End Function
Function addUrgentTask(b.bot,parametr=0,ignoreCycle=False)
If b\urgentTask=False
If (b\nextTask-1)<0 Then b\oldTask[b\nextTask] =b\nextTask Else b\oldTask[b\nextTask] =b\nextTask-1
b\nextTask = b\endTask+1
b\task[b\nextTask] = parametr
b\ignoreCycle[b\nextTask] = ignoreCycle
b\endTask = b\nextTask
countTasks = countTasks+1
b\urgentTask=True
Else If b\urgentTask=True
b\task[b\nextTask] = parametr
b\ignoreCycle[b\nextTask] = ignoreCycle
End If
End Function
Function removeAllTasks()
For i=0 To MaxTasks
countTasks = countTasks-1
b\task[b\nextTask] = 0
Next
End Function
Function addDelBot(b.bot,ignoreCycle=False)
b\task[b\nextTask] = DEL
b\ignoreCycle[b\nextTask] = ignoreCycle
End Function
Function addPause(b.bot,val,ignoreCycle=False)
If b\task[b\nextTask] = 0
b\task[b\nextTask] = pause
b\timer[b\nextTask]= val
b\timer2[b\nextTask]= val
b\ignoreCycle[b\nextTask] = ignoreCycle
b\endTask = b\nextTask
b\nextTask = b\nextTask+1
countTasks = countTasks+1
End If
End Function
Function PauseBot(b.bot)
If b\timer[b\nextTask] <= 0 Then
b\timer[b\nextTask]= b\timer2[b\nextTask]
eachTask(b)
End If
b\timer[b\nextTask]=b\timer[b\nextTask] - 1
End Function
Function PauseTask()
b\timer[b\nextTask]=timer
timer=timer - 1
If timer<=0 Then b\ignoreCycle[b\nextTask] = True
End Function
Function addSpeed(b.bot,parametr=0,setSpeed#,ignoreCycle=False)
If b\task[b\nextTask] = 0
b\task[b\nextTask] = parametr
b\speedbot[b\nextTask] = setSpeed#
b\ignoreCycle[b\nextTask] = ignoreCycle
b\endTask = b\nextTask
b\nextTask = b\nextTask+1
countTasks = countTasks+1
End If
End Function
Function eachTask(b.bot)
If b\cycle = True
If b\nextTask = b\endTask Or b\nextTask = MaxTasks Then b\nextTask = 0 : Return b\nextTask
b\nextTask =b\nextTask +1
Return b\nextTask
End If
End Function
Function SortTask(b.bot)
Local nextTask2=0, TaskNull = True ;nextTask =0 ,
For i=0 To MaxTasks
If b\task[i] > 0 Then TaskNull = False : Exit
Next
If TaskNull = False
For nextTask =0 To MaxTasks
If b\task[nextTask] = 0
For nextTask2 =nextTask +1 To MaxTasks
If nextTask2<> MaxTasks +1
If b\task[nextTask2] <>0 Then
b\task[nextTask] = b\task[nextTask2]
b\ignoreCycle[nextTask] = False
b\task[nextTask2]=0
Exit
EndIf
EndIf
Next
EndIf
Next
End If
End Function
Function deleteTask(b.bot)
countTasks = countTasks-1
b\task[b\nextTask] = 0
b\ignoreCycle[b\nextTask] = False
SortTask(b)
b\nextTask =b\nextTask -1 ; b\oldTask[b\nextTask]
b\endTask = b\endTask -1
eachTask(b)
b\urgentTask=False
End Function
Function DeleteBot(b.bot)
Delete b
End Function
Function Move(b.bot)
If b\x<b\tx Then b\x = b\x +b\speed
If b\y<b\ty Then b\y = b\y +b\speed
If b\x>b\tx Then b\x = b\x -b\speed
If b\y>b\ty Then b\y = b\y -b\speed
If dist#(b\x,b\y,b\tx,b\ty)<= b\speed+2 Then eachTask(b)
End Function
Function CheckForWorker(b.bot)
For w.bot= Each bot
If w<>b
If b\name ="zombi" And w\name ="worker" And w\state <>"DIE" And b\state <> "DIE"
If dist#(b\x,b\y,w\x,w\y)<= 15
addUrgentTask(b,ATACK)
; b\idatackbot = w\idbot
addUrgentTask(w,ATACK)
; w\idatackbot = b\idbot
Exit
EndIf
EndIf
EndIf
Next
End Function
Function SelectAction(b.bot)
If b\ignoreCycle[b\nextTask] = True
; eachTask(b)
deleteTask(b)
Else
Select b\task[b\nextTask]
Case STAY
If b\name="worker" Then resource = resource +1
b\state = "STAY"
eachTask(b)
Case GO
b\state ="GO"
; eachTask(b)
Move(b)
Case GOBACK
b\state ="GOBACK"
; eachTask(b)
Move(b)
Case WORK
b\state ="WORK"
eachTask(b)
Case ATACK
b\state ="ATACK"
For w.bot= Each bot
If w<>b
;If w<>Null
d = dist#(b\x,b\y,w\x,w\y);
If b\name ="zombi" And w\name ="worker" ; w\state <>"DIE" Or
If d<= 15 And w\task[w\nextTask] <> DIE And b\task[b\nextTask] <> DIE Then
w\live = w\live - Rand(1,5)
b\live = b\live - Rand(1,5)
If w\live <= 0 Then
w\task[w\nextTask] = DIE
b\ignoreCycle[b\nextTask] = True
Exit
ElseIf b\live <= 0 Then
b\task[b\nextTask] = DIE
w\ignoreCycle[w\nextTask] = True
Exit
EndIf
EndIf
EndIf
;EndIf
EndIf
Next
Case DIE
b\state ="DIE"
; addPause(b,1300)
; eachTask(b)
; addDelBot(b)
; b\nextTask = b\nextTask -2
Case Del
; DeleteBot(b)
Case moveto
b\state ="moveto"
b\tx = -15 : b\ty = 300
eachTask(b)
Case Random
b\state ="Random"
b\tx = Rnd(10,790) : b\ty = Rnd(10,590)
eachTask(b)
Case randomTree
b\state ="randomTree"
r= Rnd(Rnd(1,idTree-1 ),idTree-1 )
For w.bot= Each bot
If w\idTree =r
b\tx = w\x : b\ty = w\y
; Exit
EndIf
Next
eachTask(b)
Case speed
b\state ="speed"
b\speed = b\speedbot[b\nextTask]
eachTask(b)
Case pause
;b\state ="Pause"
pauseBot(b)
End Select
End If
End Function
Function CreateZombi()
b.bot = addBot.bot("zombi", True)
b\x = 400 : b\y = 300
ZombiAction(b)
End Function
Function ZombiAction(b.bot)
addTask(b,random)
addSpeed(b,speed,3) ; ,True
addTask(b,GO)
addTask(b,STAY)
addPause(b,60)
b\nextTask = 0
End Function
Function CreateWorker()
b.bot = addBot.bot("worker", True)
b\x = 10 : b\y = Rnd(300)
WorkerAction(b)
End Function
Function WorkerAction(b.bot)
addTask(b,randomtree)
addSpeed(b,speed,5)
addTask(b,GO)
addTask(b,WORK)
addPause(b,60)
addSpeed(b,speed,2)
addTask(b,moveto)
addTask(b,GOBACK)
addTask(b,STAY)
addPause(b,30)
b\nextTask = 0
End Function
Function CreateTree()
b.bot= addTree.bot("tree")
End Function
Graphics 800,600,32,2
SetBuffer BackBuffer()
For i=0 To 9
CreateTree()
Next
For i=0 To 5
CreateZombi()
Next
For i=0 To 9
CreateWorker()
Next
While Not KeyHit(1)
WaitTimer(GameTime)
Cls
If KeyHit(57)Then showText = Not showText
For b.bot = Each bot
If b<>Null
If showText = 1
Text b\x,b\y-20 ,b\timer[b\nextTask] ;"Pause: "+
Text b\x,b\y-30 ,b\Name +" : "+b\state+" : "+b\speed;+" : "+ dist#(b\x,b\y,b\tx,b\ty) ;"Name : "+
Text b\x,b\y+20 ,b\task[b\nextTask]+" : "+b\ignoreCycle[b\nextTask]
Else
Text b\x,b\y-20,b\live;+" : "+
Text b\x,b\y-30,b\timer[b\nextTask]+" : "+b\state
EndIf
If KeyHit(2)Then
;timer = 20
addUrgentTask(b,ATACK)
EndIf
Select b\name$
Case "zombi"
CheckForWorker(b)
Color 0,155,0
Select b\state
Case "STAY"
Text b\x,b\y-10,"? ! ..."
Text b\x,b\y,",-@ -,"
Case "GO"
Text b\x,b\y,"`-@ -`"
Case "ATACK"
b\pulse = Not b\pulse
If b\pulse =1 Then
Text b\x,b\y-5,"* *"
Text b\x,b\y,"} @ {"
Text b\x,b\y+9,"* *"
Else
Text b\x,b\y-5,"` `"
Text b\x,b\y," -@-"
Text b\x,b\y+6,", ,"
EndIf
Case "DIE"
Text b\x,b\y,"_t_"
End Select
Color 0,0,255
Text b\tx,b\ty,"."
SelectAction(b)
Case "worker"
Color 155,0,255
Text b\tx,b\ty,"___"
Color 255,255,0
Select b\state
Case "GO"
Text b\x,b\y,"Q:!"
Case "GOBACK"
Text b\x,b\y,"Q;#"
Case "DIE"
Text b\x,b\y,"_t_"
Case "WORK"
b\pulse = Not b\pulse
If b\pulse =1 Then Text b\x,b\y,"Q~~ " Else Text b\x,b\y,"Q---"
Case "ATACK"
b\pulse = Not b\pulse
If b\pulse =1 Then
Text b\x,b\y-5," v"
Text b\x,b\y,"Q~~"
Text b\x,b\y+5," ^ "
Else
Text b\x,b\y-5," ` ` `"
Text b\x,b\y,"Q---"
Text b\x,b\y+5," , , ,"
EndIf
End Select
SelectAction(b)
Case "tree"
Text 700,20,b\endTree
Color 0,255,0
Text b\x,b\y-16,") W ("
Color 255,0,0
Text b\x,b\y-7," `Y`"
Text b\x,b\y," | "
Text b\x,b\y+11,b\idTree+" "+(idTree -1)
End Select
Color 255,255,255
EndIf
Next
; If b\ignoreCycle[b\nextTask] = False Then ic$=" False " Else ic$=" True "
; Text 200,20 ,b\Task[b\nextTask]+" , "+b\nextTask
;Text 100,20,"countTasks = "+countTasks+" "+ic$
Text 10,20,"Resource : Wood _"+resource
Flip
Wend
Delete Each Bot
FreeTimer GameTime
End
Function Dist#( X1#, Y1#, X2#, Y2# )
Return Abs(( (X1 - X2)*(X1 - X2) + (Y1 - Y2)*(Y1 - Y2) )^0.5)
End Function