Entscheidung - Ein "psychologisches" Spielchen

Spiele, Demos, Grafikzeug und anderes unterhaltendes.
Benutzeravatar
Dostej
Beiträge: 529
Registriert: 01.10.2004 10:02
Kontaktdaten:

Entscheidung - Ein "psychologisches" Spielchen

Beitrag von Dostej »

Als Ergebnis meiner Netzwerkbemühungen habe ich mal was nachgeproggt, was sie in der Sozialpsychologie zur Erforschung von Weiss-nicht-mehr-genau-was verwendet haben.

Jedenfalls ist das Spiel extrem primitiv. Nur 4 Variablen. Das kann man praktisch nicht alleine Spielen...

Der Witz kommt eher wenn man es gegen andere spielt.

Naja, also nichts wirklich ernsthaftes. Eher als Codebeispiel für die Netzwerkfunktionen gemacht.

Code: Alles auswählen

; ein "psychologisches" Spiel(chen) von Dostej
; kann von 2-9 Spielern im LAN (oder übers Netz) gespielt werden

;{- Konstanten
; Window Constants
Enumeration
  #WND_Join_Game
  #WND_SERVERB
  #WND_CON
  #WND_Victim
  #WND_WAITSTART
EndEnumeration

; Gadget Constants
Enumeration
  #WND_SERVERB_TXT_IP
  #WND_SERVERB_Port
  #WND_SERVERB_STR_IP
  #WND_SERVERB_STR_Port
  #WND_SERVERB_BTN_Abbruch
  #WND_SERVERB_BTN_OK
  
  #CON_IMG
  #CON_LICON
  #CON_TXT_AktionsPunkte
  #CON_BTN_Prod
  #CON_BTN_Luftwaffe
  #CON_BTN_Heer
  #CON_BTN_Diplomatie
  #CON_BTN_Land
  #CON_BTN_Fertig
  #CON_IMG_Eigenfarbe
  #CON_TXT_Runde
  #CON_BTN_Spionage
  #CON_BTN_Angriff
  
  #WND_WAITSTART_PBAR
  #WND_WAITSTART_TXT_SpielerBisher
  #WND_WAITSTART_BTN_Start
  #WND_WAITSTART_BTN_Abbruch
  
  #WND_Victim_IMG_0
  #WND_Victim_TXT_0
  #WND_Victim_IMG_1
  #WND_Victim_TXT_1
  #WND_Victim_IMG_2
  #WND_Victim_TXT_2
  #WND_Victim_IMG_3
  #WND_Victim_TXT_3
  #WND_Victim_IMG_4
  #WND_Victim_TXT_4
  #WND_Victim_IMG_5
  #WND_Victim_TXT_5
  #WND_Victim_IMG_6
  #WND_Victim_TXT_6
  #WND_Victim_IMG_7
  #WND_Victim_TXT_7
  #WND_Victim_IMG_8
  #WND_Victim_TXT_8
  #WND_Victim_BTN_Abbruch
  
  #WND_Join_Game_LICON
  #WND_Join_Game_BTN_OK
  #WND_Join_Game_BTN_Abbruch
EndEnumeration

; IMages
Enumeration
  #IMG_Info
  #IMG_Farbe
  #IMG_Victim_0
  #IMG_Victim_1
  #IMG_Victim_2
  #IMG_Victim_3
  #IMG_Victim_4
  #IMG_Victim_5
  #IMG_Victim_6
  #IMG_Victim_7
  #IMG_Victim_8
EndEnumeration

;Fonts
Enumeration
  #FNT_Titel
  #FNT_Zwischen
  #FNT_Standard
EndEnumeration


#MAX_PREFERRED_LENGTH = -1 
#SV_TYPE_ALL          = $FFFFFFFF 
#NERR_SUCCESS         = 0 
#ERROR_MORE_DATA      = 234 
#MainWindow           = 100 
#MMTB                 = 200

#MAX_CLIENTS = 8
;}
;{- Strukturen und Vars
; die Systemdaten für das Netzspiel
Structure HOSTENT 
  h_name.l 
  h_aliases.l 
  h_addrtype.w 
  h_length.w 
  h_addr_list.l 
EndStructure 
Structure SERVER_INFO_101 
  dwPlatformId.l 
  lpszServerName.l 
  dwVersionMajor.l 
  dwVersionMinor.l 
  dwType.l 
  lpszComment.l 
EndStructure 
Structure LAN_RESULT
  Name.s
  IP_Name.s
  Aktiv_Server.l ; 1, wenn dort ein aktiver Server gefunden werden konnte, dann sind auch die weiteren Daten belegt
  Spiel_Name.s
  Spieler_bisher.l
EndStructure
NewList LAN_Client.LAN_RESULT()

Global Spionage ; =1, wenn der Punkt für Spionage ausgegeben wurde
Global Runde_fertig.l ; = 1, wenn der Spieler die Daten gesendet hat
Global NetzwerkID ; beinhaltet die ID des Servers
Global Spieler_nr.l ; die Spielernummer im aktuellen Spiel
Global Port.l ; enthält den verwendeten Port. Standardmässig ist das 1000
; Die Spieldaten
Structure ply
  Aktiv.l ; =1, wenn Spieler aktiv
  Runde.l ; Rundennummer
  Aktionspunkte.l ; die restlichen Aktionspunkte für diese Runde
  Produktion.l ; Ergibt die Aktionspunkte
  Luftwaffe.l ; Anzahl der Flieger
  Heer.l ; Anzahl der Truppen
  Land.l ; Landgrösse
  Victim.l ; = -1, wenn niemand angegriffen werden soll, ansonsten die Spielernummer
  Victim_davor.l ; speichert den Ziel der letzten Runde
EndStructure
Dim player.ply(#MAX_CLIENTS)

Dim col.l(#MAX_CLIENTS)
col(0) = $00FFFF
col(1) = $0000FF
col(2) = $00FF00
col(3) = $FF0000
col(4) = $FF00FF
col(5) = $0080FF
col(6) = $FFFF00
col(7) = $FFFFFF
col(8) = $800080

Global Ownpath.s
CompilerIf #jaPBe_IsExecute
Ownpath = Space(1000) 
GetModuleFileName_(0,@Ownpath,1000) 
Ownpath = GetPathPart(Ownpath)
CompilerElse 
Ownpath = "C:\PureBasic\projects\Entscheidungen\"
CompilerEndIf

;}
;{- Bilder
CreateImage(#IMG_Info, 500, 510)
CreateImage(#IMG_Farbe, 30, 30)
CreateImage(#IMG_Victim_0, 30, 30)
CreateImage(#IMG_Victim_1, 30, 30)
CreateImage(#IMG_Victim_2, 30, 30)
CreateImage(#IMG_Victim_3, 30, 30)
CreateImage(#IMG_Victim_4, 30, 30)
CreateImage(#IMG_Victim_5, 30, 30)
CreateImage(#IMG_Victim_6, 30, 30)
CreateImage(#IMG_Victim_7, 30, 30)
CreateImage(#IMG_Victim_8, 30, 30)
For x = #IMG_Victim_0 To #IMG_Victim_8 ; die Bilder kolorieren
  UseImage(x)
  StartDrawing(ImageOutput())
  Box(0, 0, 30, 30, col(x-#IMG_Victim_0))
  StopDrawing()
Next
;}
;{- Sonstiges
LoadFont(#FNT_Titel, "Arial", 24, #PB_Font_Bold | #PB_Font_Italic)
LoadFont(#FNT_Zwischen, "Arial", 16, #PB_Font_Bold)
LoadFont(#FNT_Standard, "Arial", 11)
;}
;{- Initialisieren
If InitSprite() And InitKeyboard() And InitNetwork() = 0
  MessageRequester("Error", "Cant initialize Core")
  End
EndIf
;}
;{- Proceduren
; Core
Procedure ArraySize(*Array) 
  ProcedureReturn PeekL(*Array-8) 
EndProcedure 

; Server anmeldung
Procedure.l Input_Server_Connections()
  ; Gibt 1 zurück, wenn ok, ansonsten -1
  back.l = -1
  If OpenWindow(#WND_SERVERB, 270, 248, 295, 110,  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar , "Verbindungsdaten zum Server einegben", UseWindow(#WND_CON))
    If CreateGadgetList(WindowID())
      TextGadget(#WND_SERVERB_TXT_IP, 10, 10, 120, 20, "IP Adresse", #PB_Text_Border)
      TextGadget(#WND_SERVERB_Port, 10, 40, 120, 20, "Verwendeter Port", #PB_Text_Border)
      IPAddressGadget(#WND_SERVERB_STR_IP, 140, 10, 150, 20)
      StringGadget(#WND_SERVERB_STR_Port, 140, 40, 70, 20, "1000", #PB_String_Numeric)
      ButtonGadget(#WND_SERVERB_BTN_Abbruch, 40, 80, 90, 20, "Abbruch")
      ButtonGadget(#WND_SERVERB_BTN_OK, 140, 80, 90, 20, "OK")
      
      SetGadgetState(#WND_SERVERB_STR_IP, MakeIPAddress(127, 0, 0, 1))
      
      Repeat ; Start of the event loop 
        Event = WaitWindowEvent() ; This line waits until an event is received from Windows 
        WindowID = EventWindowID() ; The Window where the event is generated, can be used in the gadget procedures
        GadgetID = EventGadgetID() ; Is it a gadget event? 
        EventType = EventType() ; The event type 
        
        If Event = #PB_EventGadget 
          If GadgetID = #WND_SERVERB_BTN_Abbruch
            Event = #PB_Event_CloseWindow
            back = -1
          ElseIf GadgetID = #WND_SERVERB_BTN_OK
            Event = #PB_Event_CloseWindow
            back = 1
          EndIf 
        EndIf 
      Until Event = #PB_Event_CloseWindow ; End of the event loop
      Event = 0
      AddElement(LAN_Client())
      LAN_Client()\IP_Name = IPString(GetGadgetState(#WND_SERVERB_STR_IP))
      Debug "ip: " + LAN_Client()\IP_Name
      Port = Val(GetGadgetText(#WND_SERVERB_STR_Port))
      CloseWindow(#WND_SERVERB)
      ; Versuche die Verbindung zum Server herzustellen und anzumelden
      ; NetzwerkID = LAN_Client()\Aktiv_Server
      ; SpielName.s = LAN_Client()\Spiel_Name
      
    EndIf
  EndIf
  ProcedureReturn back
EndProcedure
Procedure.s GetIPbyName (NameIP.s) 
  TheIPAdress.s 
  pHostinfo = gethostbyname_(NameIP) 
  If pHostinfo = 0 
    TheIPAdress = "Unable to resolve domain name" 
  Else 
    CopyMemory (pHostinfo, hostinfo.HOSTENT, SizeOf(HOSTENT)) 
    If hostinfo\h_addrtype <> #AF_INET 
      MessageRequester("Info","A non-IP address was returned",0) 
    Else 
      While PeekL(hostinfo\h_addr_list+AdressNumber*4) 
        ipAddress = PeekL(hostinfo\h_addr_list+AdressNumber*4) 
        TheIPAdress = StrU(PeekB(ipAddress),0)+"."+StrU(PeekB(ipAddress+1),0)+"."+StrU(PeekB(ipAddress+2),0)+"."+StrU(PeekB(ipAddress+3),0) 
        AdressNumber+1 
      Wend 
    EndIf 
  EndIf 
  ProcedureReturn TheIPAdress 
EndProcedure 
Procedure GetLANList() 
  IPResult.s 
  se101.SERVER_INFO_101 
  nStructSize = SizeOf(SERVER_INFO_101) 
  RetCode = NetServerEnum_(0, 101, @bufptr, #MAX_PREFERRED_LENGTH, @dwEntriesread, @dwTotalentries, #SV_TYPE_ALL, 0, @dwResumehandle) 
  If RetCode = #NERR_SUCCESS And RetCode <> #ERROR_MORE_DATA 
    For i = 0 To dwEntriesread - 1 
      CopyMemory( bufptr + (nStructSize * i),@se101, nStructSize) 
      Buffer.s=Space(512) 
      result=WideCharToMultiByte_(#CP_ACP, 0, se101\lpszServerName, 255, @Buffer.s, 512, 0, 0) 
      IPResult = GetIPbyName (Buffer) 
      AddElement(LAN_Client())
      LAN_Client()\Name = Buffer
      LAN_Client()\IP_Name = IPResult
    Next 
  Else 
    MessageRequester("Info","Failed",0) 
  EndIf 
  NetApiBufferFree_(bufptr) 
  ; SendMessage_(MMTextBox,$00B6,0,30) 
EndProcedure 
Procedure.l Open_WND_Join_Game()
  ; wählt ein Spiel aus und schliesst die offenen Verbindungen zu anderen Spielservern
  ; Gibt den Listindex des gewählten Lan-Spiels zurück, oder -1, wenn keines gewählt wurde
  back.l = -1
  If OpenWindow(#WND_Join_Game, 216, 0, 313, 399,  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar , "Join Game", UseWindow(#WND_CON))
    If CreateGadgetList(WindowID())
      
      ;-
      ListIconGadget(#WND_Join_Game_LICON, 10, 30, 290, 330, "Spiel Name", 200)
      AddGadgetColumn(#WND_Join_Game_LICON, 2, "Spieler bisher", 85)
      AddGadgetColumn(#WND_Join_Game_LICON, 3, "", 1)
      ButtonGadget(#WND_Join_Game_BTN_OK, 230, 370, 70, 20, "OK")
      ButtonGadget(#WND_Join_Game_BTN_Abbruch, 10, 370, 70, 20, "Abbruch")
      
      ; die Gadgets vorbereiten
      ResetList(LAN_Client())
      While NextElement(LAN_Client())
        If LAN_Client()\Aktiv_Server
          AddGadgetItem(#WND_Join_Game_LICON, -1, LAN_Client()\Name + " - " + LAN_Client()\Spiel_Name + Chr(10) + Str(LAN_Client()\Spieler_bisher) + Chr(10) + Str(ListIndex(LAN_Client())))
        EndIf
      Wend
      
      ; Aktionsschleife
      Repeat 
        Event = WaitWindowEvent() 
        If Event = #PB_EventGadget
          GadgetID = EventGadgetID() 
          If GadgetID = #WND_Join_Game_LICON
            back = Val(GetGadgetItemText(#WND_Join_Game_LICON, GetGadgetState(#WND_Join_Game_LICON), 2)) ; den index auslesen
            
          ElseIf GadgetID = #WND_Join_Game_BTN_OK
            Event = #PB_EventCloseWindow
            
          ElseIf GadgetID = #WND_Join_Game_BTN_Abbruch
            back = -1
            Event = #PB_EventCloseWindow
            
          EndIf 
        EndIf 
      Until Event = #PB_EventCloseWindow
      Event = 0 ; nur dieses Fenster schliessen
      ; die anderen offenen Serververbindungen schliessen
      ResetList(LAN_Client())
      While NextElement(LAN_Client())
        If LAN_Client()\Aktiv_Server And ListIndex(LAN_Client()) <> back ; wenn server, aber nicht der ausgewählte
          CloseNetworkConnection(LAN_Client()\Aktiv_Server)
        EndIf
      Wend
      CloseWindow(#WND_Join_Game)
    EndIf
  EndIf
  ProcedureReturn back
EndProcedure
Procedure.l Register_at_Server()
  ; registriert den Client am Server
  t.l = 1
  ; Am Spiel anmelden
  Msg.s = "1" ; Bitte um Anmeldung beim Spiel
  SendNetworkData(NetzwerkID, @Msg, 1) ; anmeldung für Spiel schicken 
  Msg = "    "
  Debug "spielnr vor dem Bestätigungsstring " + Str(Spieler_nr)
  Repeat ; warte auf die Anmeldebestätigung 
    If NetworkClientEvent(NetzwerkID) = 2
      ReceiveNetworkData(NetzwerkID, @Msg, 3)
      Msg = RTrim(Msg)
      Debug "anmeldestring - bestätigung direkteingabe: " + Msg
      Spieler_nr = Val(Right(Msg, 1))
      LAN_Client()\Spieler_bisher = Val(Left(Msg, 1))
      Debug "Spieler_Nr erhalten: " + Str(Spieler_nr)
    EndIf
    Delay(100) ; 10 Abfragen pro Sek langen
  Until Spieler_nr > -1
  If Spieler_nr = 9 ;  Kein platz mehr
    Spieler_nr = -1
    t = -1
    MessageRequester("Fehler", "Alle Plätze sind bereits besetzt")
  EndIf
  ProcedureReturn t
EndProcedure

; Spieldaten übers Netz
Procedure Send_Game_Data()
  ; schickt die Spieldaten an den Server
  If NetzwerkID
    SendNetworkData(NetzwerkID, @player(Spieler_nr), SizeOf(ply))
    Debug "Spieldaten an Server gesendet"
  Else
    MessageRequester("Fehler", "Kein Spielserver bekannt")
  EndIf
EndProcedure
Procedure Get_Net_Data()
  ; testet, ob Daten vom Server gekommen sind
  
EndProcedure
Procedure.l Receive_Game_Data()
  ; empfängt die Spieldaten vom Server
  t.l = -1
  If NetzwerkID
    Repeat ; warten, bis die neuen Rundendaten vom Server da sind
      If NetworkClientEvent(NetzwerkID) = 2
        Debug "size array: " + Str(SizeOf(ply) * ArraySize(@player()))
        Debug "structsize: " + Str(SizeOf(ply))
        Debug  " received: " + Str(ReceiveNetworkData(NetzwerkID, @player(), SizeOf(ply) * ArraySize(@player())))
        t = 1
      EndIf
      Delay(100)
    Until t > -1
    
    ; MessageRequester("Rundenbeginn", "Runde " + Str(player(Spieler_nr)\Runde) )
    s.s = ""
    For x = 0 To #MAX_CLIENTS
      If player(x)\Aktiv
        If player(x)\Victim_davor = Spieler_nr
          s = s + Chr(13) + Chr(10) + "- Spieler " + Str(x)
        EndIf
      EndIf
    Next
    If s <> "" ; wenn Angriffe stattfanden
      MessageRequester("Kriegsbricht", "Sie wurden angegriffen von:" + s)
    EndIf
    
    
    Runde_fertig = 0 ;  nächste Runde
    Spionage = 0 ; Spionage auf 0 gesetzt
    DisableGadget(#CON_BTN_Spionage, 0)
  Else
    MessageRequester("Fehler", "Es läuft kein Spiel")
  EndIf
  ProcedureReturn back
EndProcedure

; Sonstiges
Procedure Refresh_Data()
  ; baut die Spieldaten neu auf
  Debug "refresh Data"
  SetGadgetText(#CON_TXT_AktionsPunkte, "Aktionspunkte: " + Str(player(Spieler_nr)\Aktionspunkte))
  SetGadgetText(#CON_TXT_Runde, "Runde: " + Str(player(Spieler_nr)\Runde))
  ClearGadgetItemList(#CON_LICON)
  AddGadgetItem(#CON_LICON, -1, "Produktion" + Chr(10) + Str(player(Spieler_nr)\Produktion))
  AddGadgetItem(#CON_LICON, -1, "Luftwaffe" + Chr(10) + Str(player(Spieler_nr)\Luftwaffe))
  AddGadgetItem(#CON_LICON, -1, "Heer" + Chr(10) + Str(player(Spieler_nr)\Heer))
  AddGadgetItem(#CON_LICON, -1, "Land" + Chr(10) + Str(player(Spieler_nr)\Land))
  If player(Spieler_nr)\Victim > -1
    AddGadgetItem(#CON_LICON, -1, "Angriff auf" + Chr(10) + "Spieler " + Str(player(Spieler_nr)\Victim))
  EndIf
  SetGadgetState(#CON_IMG, UseImage(#IMG_Info))
  UseImage(#IMG_Farbe)
  StartDrawing(ImageOutput())
  Box(0, 0, 30, 30, col(Spieler_nr))
  StopDrawing() 
  SetGadgetState(#CON_IMG_Eigenfarbe, UseImage(#IMG_Farbe))
EndProcedure
Procedure Paint_Info()
  ; zeichnet das grosse img
  UseImage(#IMG_Info)
  StartDrawing(ImageOutput())
  Box(0, 0, 500, 510, $C0C0C0)
  DrawingMode(1)
  If player(x)\Runde = 0 ; wenn noch nicht angefangen
    ;{ Grundlegende Infos anzeigen
    cnt.l = 10 
    Locate(100, cnt)
    DrawingFont(UseFont(#FNT_Titel))
    DrawText("Entscheidung")
    DrawingFont(UseFont(#FNT_Standard))
    cnt + 55 : Locate(10, cnt) 
    
    
    DrawText("Das Spiel ist denkbar einfach, um nicht zu sagen primitiv")
    cnt + 20 : Locate(10, cnt)
    DrawText("Alleine zu spielen ist es gähnend langweilig. Denn das Spiel")
    cnt + 20 : Locate(10, cnt)
    DrawText("gewinnt seinen Reiz durch die Einschätzung des Gegners.")
    cnt + 20 : Locate(10, cnt)
    DrawText("(Besonders wenn man es mehrmals hintereinander spielt)")
    
    cnt + 35 : Locate(10, cnt)
    DrawingFont(UseFont(#FNT_Zwischen))
    DrawText("Spielregeln")
    DrawingFont(UseFont(#FNT_Standard))
    cnt + 30 : Locate(10, cnt)
    DrawText("Sie haben ein Land, mit Armee und Produktion. Das haben alle Spieler.")
    cnt + 20 : Locate(10, cnt)
    DrawText("Sie haben pro Runde so viele Aktionspunkte, wie sie Produktion haben.")
    cnt + 20 : Locate(10, cnt)
    DrawText("Pro Aktionpunkt können sie 1 Produktion, Armeeeinheit oder Land kaufen.")
    cnt + 20 : Locate(10, cnt)
    DrawText("Oder sich über die Spieldaten der anderen Spieler informieren (Spionage).")
    
    cnt + 25 : Locate(10, cnt)
    DrawText("Um ihre Armee zu unterhalten, benötigen sie je Einheit 1 Produktion.")
    cnt + 20 : Locate(10, cnt)
    DrawText("Die Grösse des Landes begrenzt die Anzahl der Produktion.")
    cnt + 25 : Locate(10, cnt)
    DrawText("Sie können andere Spieler mit ihrer Armee angreifen.")
    cnt + 20 : Locate(10, cnt)
    DrawText("Dabei zerstört die Luftwaffe die Produktion des Gegners")
    cnt + 20 : Locate(10, cnt)
    DrawText("und das Heer erbeutet evtl. Land vom Gegner.")
    cnt + 30 : Locate(10, cnt)
    DrawText("Der Spionagebericht zeigt die aktuellen Daten des Gegners an, bis auf den")
    cnt + 20 : Locate(10, cnt)
    DrawText("Kreigsbericht, der zeigt den Angriff der letzten Runde.")
    cnt + 60 : Locate(10, cnt)
    DrawText("Um das Spiel zu starten klicken sie mit der Maus.")
    
    cnt + 20 : Locate(10, cnt)
    DrawText("")
    
    StopDrawing()
    SetGadgetState(#CON_IMG, UseImage(#IMG_Info))
    Repeat 
      Event = WaitWindowEvent() ; This line waits until an event is received from Windows 
    Until EventType() = #PB_EventType_LeftClick
    ;}
  Else
    ;{ Der Spionagebericht
    Debug "zeichne info"
    For x = 0 To #MAX_CLIENTS ; das Infofeld zeichnen
      If player(x)\Aktiv
        Box(5, 10 + x * 55, 30, 30, col(x))
        If Spionage
          Locate(50, 15 + x * 55)
          s.s = "   Land: " + Str(player(x)\Land)
          s = s + "   Prod: " + Str(player(x)\Produktion) 
          s = s + "   Luftwaffe: " + Str(player(x)\Luftwaffe) 
          s = s + "   Heer: " + Str(player(x)\Heer) 
          If player(x)\Victim_davor <> -1
            s = s + "   Krieg Spl: " + Str(player(x)\Victim_davor) 
          Else
            s = s + "   ---" 
          EndIf
          
          DrawText("Spieler " + Str(x) + s)
        EndIf
      EndIf
    Next
    StopDrawing()
    SetGadgetState(#CON_IMG, UseImage(#IMG_Info))
    ;}
  EndIf
  
EndProcedure
Procedure.l Choose_Victim()
  ; sucht ein Opfer für den Angriff aus
  back.l = -1
  If OpenWindow(#WND_Victim, 216, 0, 190, 410,  #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered , "Wählen Sie ein Angriffsziel", UseWindow(#WND_CON))
    If CreateGadgetList(WindowID())
      For x = 0 To #MAX_CLIENTS
        If player(x)\Aktiv And x <> Spieler_nr ;nicht sich selbst
          ImageGadget(#WND_Victim_IMG_0 + x * 2, 10, 15 + x * 40, 30, 30, UseImage(#IMG_Victim_0 + x))
          TextGadget(#WND_Victim_TXT_0 + x * 2, 60, 20 + x * 40, 120, 20, "Spieler " + Str(x), #PB_Text_Border)
        EndIf
      Next
      ButtonGadget(#WND_Victim_BTN_Abbruch, 50, 380, 90, 20, "Abbruch")
      
      
      Repeat ; Start of the event loop 
        Event = WaitWindowEvent() ; This line waits until an event is received from Windows
        WindowID = EventWindowID() ; The Window where the event is generated, can be used in the gadget procedures
        GadgetID = EventGadgetID() ; Is it a gadget event?
        EventType = EventType() ; The event type
        ;You can place code here, and use the result as parameters for the procedures
        If Event = #PB_EventGadget 
          If GadgetID = #WND_Victim_BTN_Abbruch
            Event = #PB_Event_CloseWindow
            
          ElseIf GadgetID = #WND_Victim_IMG_0
            back = 0
          ElseIf GadgetID = #WND_Victim_IMG_1
            back = 1
          ElseIf GadgetID = #WND_Victim_IMG_2
            back = 2
          ElseIf GadgetID = #WND_Victim_IMG_3
            back = 3
          ElseIf GadgetID = #WND_Victim_IMG_4
            back = 4
          ElseIf GadgetID = #WND_Victim_IMG_5
            back = 5
          ElseIf GadgetID = #WND_Victim_IMG_6
            back = 6
          ElseIf GadgetID = #WND_Victim_IMG_7
            back = 7
          ElseIf GadgetID = #WND_Victim_IMG_8
            back = 8 
          EndIf 
        EndIf 
      Until Event = #PB_Event_CloseWindow Or back <> -1 ; End of the event loop
      Event = 0
      CloseWindow(#WND_Victim)
    EndIf
  EndIf
  ProcedureReturn back
EndProcedure

Procedure Open_Game_Win()
  If OpenWindow(#WND_CON, 216, 0, 766, 531, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_TitleBar , "Entscheidungen")
    If CreateGadgetList(WindowID())
      ;{- Fenster aufbauen
      ImageGadget(#CON_IMG, 10, 10, 500, 510, UseImage(#IMG_Info), #PB_Image_Border)
      
      ;-
      ListIconGadget(#CON_LICON, 530, 10, 230, 160, "Land", 145)
      AddGadgetColumn(#CON_LICON, 1, "Werte", 80)
      TextGadget(#CON_TXT_AktionsPunkte, 530, 240, 230, 20, "")
      ButtonGadget(#CON_BTN_Prod, 530, 270, 110, 30, "Produktion")
      ButtonGadget(#CON_BTN_Luftwaffe, 530, 310, 110, 30, "Luftwaffe")
      ButtonGadget(#CON_BTN_Heer, 530, 350, 110, 30, "Heer")
      ButtonGadget(#CON_BTN_Land, 530, 390, 110, 30, "Land")
      ;ButtonGadget(#CON_BTN_Diplomatie, 650, 270, 110, 30, "Diplomatie")
      ButtonGadget(#CON_BTN_Fertig, 650, 490, 110, 30, "Fertig")
      ImageGadget(#CON_IMG_Eigenfarbe, 530, 190, 30, 30, UseImage(#IMG_Farbe), #PB_Image_Border)
      TextGadget(#CON_TXT_Runde, 580, 200, 150, 20, "Runde: " + Str(player(Spieler_nr)\Runde))
      ButtonGadget(#CON_BTN_Spionage, 650, 310, 110, 30, "Spionage")
      ButtonGadget(#CON_BTN_Angriff, 530, 440, 110, 30, "Angriff auf...") 
      ;}
      
      ; Spielregeln anzeigen
      Paint_Info() ; hält das Spiel bei Runde 0 an
      Spieler_nr = -1
      Repeat ; Schleife bis alles für den Spielstart parat ist
        ;{- Spielart abfragen
        t.l = -1
        Repeat ; solange, bis eine Verbindung steht
          If MessageRequester("Spielart wählen", " Wollen Sie ein neues Spiel starten (Ja)" + Chr(13) + Chr(10) + "Oder einem bereits bestehendem Spiel beitreten (Nein)", #PB_MessageRequester_YesNo) = 6
            If CreateFile(0, Ownpath + "ServerParam.txt")
              WriteStringN("1000, Spiel" + FormatDate("%yy%mm%dd%hh%ii%ss", Date()))
              CloseFile(0)
            EndIf
            If RunProgram(Ownpath + "Entscheidungen Server.exe", "", "") ; Startet den Server
              ;{ meldet sich beim Server an
              AddElement(LAN_Client())
              LAN_Client()\IP_Name = "127.0.0.1" ; der eigene Rechner
              Port = 1000
              NetzwerkID = OpenNetworkConnection(LAN_Client()\IP_Name, Port) 
              If NetzwerkID ; wenn die Verbindung aufgebaut werden konnte
                LAN_Client()\Aktiv_Server = NetzwerkID
                Debug "netzwerkID gefunden: " + Str(NetzwerkID)
                Msg.s = Space(20)
                If ReceiveNetworkData(NetzwerkID, @Msg, 20)
                  Debug "received: " + Msg
                  LAN_Client()\Spieler_bisher = Val(Left(Msg, 1))
                  Msg = RTrim(Msg) 
                  LAN_Client()\Spiel_Name = Right(Msg, Len(Msg)-1)
                  Debug "Spiel gefunden: " + LAN_Client()\Spiel_Name
                  c + 1
                  ;If MessageRequester("Spielserver gefunden", "Es wurde folgendes Spiel gefunden" + Chr(13) + Chr(10) + Chr(13) + Chr(10) + LAN_Client()\Spiel_Name  + "    mit bisher " + Str(LAN_Client()\Spieler_bisher) + " Spielern" + Chr(13) + Chr(10) + Chr(13) + Chr(10) +"Wollen Sie an diesem Spiel mitspielen", #PB_MessageRequester_YesNo) = 6
                  t = Register_at_Server() ; am Server anmelden
                  ; Else
                    ; t = -1
                  ; EndIf 
                EndIf
              Else
                MessageRequester("Fehler", "An der angegebenen Verbindung wurde kein Spielserver gefunden")
                t = -1 ; Neuer Versuch
              EndIf
              ;}
            Else
              MessageRequester("Fehler", "Kann kein neues Spiel starten" + Chr(13) + Chr(10) + "Versuchen sie, die Datei 'Entscheidungen Server' manuell zu starten")
            EndIf
          Else ; bei bestehndem Spiel anmelden
            If MessageRequester("Verbindungswahl", " Wollen Sie die IP-Adresse des Servers selbst eingeben" + Chr(13) + Chr(10) + "Oder das LAN nach einem bereits bestehendem Spiel durchsuchen (Nein)", #PB_MessageRequester_YesNo) = 6
              ; die Daten selbst eingeben
              t = Input_Server_Connections() ; 1, wenn eingegeben oder -1 wenn abbruch
              If t = 1
                ;{ Ist an der angegebenen Verbindung ein Spielserver
                NetzwerkID = OpenNetworkConnection(LAN_Client()\IP_Name, Port) 
                If NetzwerkID ; wenn die Verbindung aufgebaut werden konnte
                  LAN_Client()\Aktiv_Server = NetzwerkID
                  Debug "netzwerkID gefunden: " + Str(NetzwerkID)
                  Msg.s = Space(20)
                  If ReceiveNetworkData(NetzwerkID, @Msg, 20)
                    Debug "received: " + Msg
                    LAN_Client()\Spieler_bisher = Val(Left(Msg, 1))
                    Msg = RTrim(Msg) 
                    LAN_Client()\Spiel_Name = Right(Msg, Len(Msg)-1)
                    Debug "Spiel gefunden: " + LAN_Client()\Spiel_Name
                    c + 1
                    If MessageRequester("Spielserver gefunden", "Es wurde folgendes Spiel gefunden" + Chr(13) + Chr(10) + Chr(13) + Chr(10) + LAN_Client()\Spiel_Name  + "    mit bisher " + Str(LAN_Client()\Spieler_bisher) + " Spielern" + Chr(13) + Chr(10) + Chr(13) + Chr(10) +"Wollen Sie an diesem Spiel mitspielen", #PB_MessageRequester_YesNo) = 6
                      t = Register_at_Server()
                    Else
                      t = -1
                    EndIf 
                  EndIf
                Else
                  MessageRequester("Fehler", "An der angegebenen Verbindung wurde kein Spielserver gefunden")
                  t = -1 ; Neuer Versuch
                EndIf
                ;}
              EndIf
            Else
              ;{ LAN durchsuchen und am Server anmelden
              ; Welche Clients gibts im Lan
              Debug "get lan list"
              GetLANList()
              ;{ teste die Lan-Computer auf Spiel-Server
              Port.l = 1000
              c.l = 0
              ResetList(LAN_Client())
              While NextElement(LAN_Client())
                Debug Str(ListIndex(LAN_Client())) + "- " + LAN_Client()\Name + " -> " + LAN_Client()\IP_Name
                ; auf welchen Clients läuft ein Server für das Spiel
                NetzwerkID = OpenNetworkConnection(LAN_Client()\IP_Name, Port) 
                If NetzwerkID ; wenn die Verbindung aufgebaut werden konnte
                  LAN_Client()\Aktiv_Server = NetzwerkID
                  Debug "netzwerkID gefunden: " + Str(NetzwerkID)
                  Msg.s = Space(20)
                  If ReceiveNetworkData(NetzwerkID, @Msg, 20)
                    Debug "received: " + Msg
                    LAN_Client()\Spieler_bisher = Val(Left(Msg, 1))
                    Msg = RTrim(Msg) 
                    LAN_Client()\Spiel_Name = Right(Msg, Len(Msg)-1)
                    Debug "Spiel gefunden: " + LAN_Client()\Spiel_Name
                    c + 1
                  EndIf
                EndIf 
              Wend
              Debug "alle server getestet"
              ResetList(LAN_Client())
              While NextElement(LAN_Client())
                ; zeigt die gefunden server, wenn die letzte Zahl <> 0, läuft dort ein Server
                Debug Str(ListIndex(LAN_Client())) + "- " + LAN_Client()\Name + " -> " + LAN_Client()\IP_Name + " - Erg: " + Str(LAN_Client()\Aktiv_Server)
              Wend
              ;}
              ;{ Auswählen, welches Spiel mitgespielt werden soll
              Spieler_nr = -1 ; 1, wenn angemeldet
              If c
                t = Open_WND_Join_Game() ; wählt ein Spiel aus und schliesst die offenen Verbindungen zu anderen Spielservern
                Debug "t: " + Str(t)
                If t > -1 ; Spiel wurde ausgewählt
                  ; die Verbindungsdaten übertragen
                  SelectElement(LAN_Client(), t)
                  Debug "listindex: " + Str(ListIndex(LAN_Client()))
                  NetzwerkID = LAN_Client()\Aktiv_Server
                  SpielName.s = LAN_Client()\Spiel_Name
                  ; die Anmeldung am Spielserver machen
                  Debug "verbindungsdaten: ID: " + Str(NetzwerkID) + ". " + SpielName
                  t = Register_at_Server()
                EndIf
              Else
                MessageRequester("Problem", "Keine Spiele zum Mitspielen vorhanden")
                t = -1
              EndIf
              ;}
              ;}
            EndIf
          EndIf
        Until t <> -1
        ;}
        ;{- Warte auf Spielbeginn
        Debug "warte auf Spielstart - spielrnr " + Str(Spieler_nr)
        
        If OpenWindow(#WND_WAITSTART, 216, 168, 414, 132,  #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_TitleBar , "Warten auf Spielstart", UseWindow(#WND_CON))
          If CreateGadgetList(WindowID())
            ProgressBarGadget(#WND_WAITSTART_PBAR, 20, 20, 360, 20, 0, 10, #PB_ProgressBar_Smooth)
            TextGadget(#WND_WAITSTART_TXT_SpielerBisher, 20, 50, 180, 20, "Bisher angemeldete Spieler: " + Str(LAN_Client()\Spieler_bisher), #PB_Text_Border)
            ButtonGadget(#WND_WAITSTART_BTN_Abbruch, 150, 100, 80, 20, "Abbrechen")
            If Spieler_nr = 0 ; wenn Startspieler, der darf Spiel evtl. früher starten
              ButtonGadget(#WND_WAITSTART_BTN_Start, 310, 100, 80, 20, "Spiel starten")
            EndIf 
            
            ; Progressbar setzen
            Debug "Spieler bisher: " + Str(LAN_Client()\Spieler_bisher)
            SetGadgetState(#WND_WAITSTART_PBAR, LAN_Client()\Spieler_bisher)
            
            Repeat ; Start of the event loop 
              Event = WindowEvent() ; This line waits until an event is received from Windows
              GadgetID = EventGadgetID() ; Is it a gadget event? 
              
              If NetworkClientEvent(NetzwerkID) = 2 ; Abfragen ob Spielstart erfolgt oder neuer Spieler dabei
                Msg = "   "
                ReceiveNetworkData(NetzwerkID, @Msg, 2)
                Msg = RTrim(Msg)
                Debug "eingang für SPielstart: " + Msg + " / " + Str(Val(Msg))
                If Msg <> "ST" ; wenn nicht Spielstart, dann neuer Mitspieler
                  Debug "msg nun: " + Msg
                  SetGadgetState(#WND_WAITSTART_PBAR, Val(Msg))
                  SetGadgetText(#WND_WAITSTART_TXT_SpielerBisher, "Bisher angemeldete Spieler: " + Msg)
                EndIf
              EndIf
              
              If Event = #PB_EventGadget 
                If GadgetID = #WND_WAITSTART_BTN_Start 
                  ; Sende Startcode an Server
                  Msg = "ST"
                  SendNetworkData(NetzwerkID, @Msg, 2)
                  Msg = "  " ;   Nun auf die Startbestätigung warten
                  
                ElseIf GadgetID = #WND_WAITSTART_BTN_Abbruch
                  Event = #PB_Event_CloseWindow
                  
                EndIf 
              EndIf
              Delay(10)
            Until Event = #PB_Event_CloseWindow Or Msg = "ST" ; End of the event loop 
            Event = 0
            CloseWindow(#WND_WAITSTART)
            ; Warte auf die Startdaten vom Server
            Debug "warte auf Spieldaten - spielbeginn"
            t = Receive_Game_Data()
          EndIf
        EndIf
      Until t <> -1
      ;} 
      Debug "runde: " +Str(Runde)
      Paint_Info()
      Refresh_Data() ; vorab 1x aufbauen
      Repeat ;{- Aktionsschleife
        Event = WindowEvent() ; This line waits until an event is received from Windows 
        WindowID = EventWindowID() ; The Window where the event is generated, can be used in the gadget procedures
        GadgetID = EventGadgetID() ; Is it a gadget event?
        EventType = EventType() ; The event type
        
        ; Get_Net_Data() ; testet, ob Daten vom Server gekommen sind
        If Runde_fertig
          Receive_Game_Data() ; wenn fertig, warte auf die nächste Runde
          Paint_Info()
          Refresh_Data()
        EndIf
        
        If Event = #PB_EventGadget 
          If GadgetID = #CON_BTN_Prod
            If Runde_fertig = 0 And player(Spieler_nr)\Aktionspunkte
              If player(Spieler_nr)\Produktion < player(Spieler_nr)\Land 
                player(Spieler_nr)\Aktionspunkte - 1
                player(Spieler_nr)\Produktion + 1
                Refresh_Data()
              Else
                MessageRequester("Problem", "Nicht genug Land, um weitere Produktion zu bauen")
              EndIf
            EndIf
            
          ElseIf GadgetID = #CON_BTN_Luftwaffe
            If Runde_fertig = 0 And player(Spieler_nr)\Aktionspunkte
              player(Spieler_nr)\Aktionspunkte - 1
              player(Spieler_nr)\Luftwaffe + 1
              Refresh_Data()
            EndIf
            
          ElseIf GadgetID = #CON_BTN_Heer
            If Runde_fertig = 0 And player(Spieler_nr)\Aktionspunkte
              player(Spieler_nr)\Aktionspunkte - 1
              player(Spieler_nr)\Heer + 1
              Refresh_Data()
            EndIf
            
          ElseIf GadgetID = #CON_BTN_Diplomatie
            
          ElseIf GadgetID = #CON_BTN_Spionage
            ; Zeige die Daten der Gegner an
            If Runde_fertig = 0 And player(Spieler_nr)\Aktionspunkte
              player(Spieler_nr)\Aktionspunkte - 1
              Spionage = 1
              Paint_Info()
              Refresh_Data()
              DisableGadget(#CON_BTN_Spionage, 1)
            EndIf
            
          ElseIf GadgetID = #CON_BTN_Angriff
            temp.l = Choose_Victim()
            If temp <> -1
              player(Spieler_nr)\Victim = Choose_Victim()
            EndIf
            Refresh_Data()
            
          ElseIf GadgetID = #CON_BTN_Land
            If Runde_fertig = 0 And player(Spieler_nr)\Aktionspunkte
              player(Spieler_nr)\Aktionspunkte - 1
              player(Spieler_nr)\Land + 1
              Paint_Info()
              Refresh_Data()
              DisableGadget(#CON_BTN_Spionage, 1)
            EndIf 
            
          ElseIf GadgetID = #CON_BTN_Fertig
            ; Die Daten an den Server senden
            If Runde_fertig = 0
              Send_Game_Data()
              Runde_fertig = 1
            EndIf
          EndIf 
        EndIf
        ;}
        Delay(10)
      Until Event = #PB_Event_CloseWindow ; End of the event loop
    EndIf
  EndIf
EndProcedure
;}

;- das eigentliche Spiel
Open_Game_Win()
End
und der Server:

Code: Alles auswählen

;{- Konstanten
#MAX_CLIENTS = 8

;}
;{- Die Spieldaten
Structure ply
  Aktiv.l ; =1, wenn Spieler aktiv
  Runde.l ; Rundennummer
  Aktionspunkte.l ; die restlichen Aktionspunkte für diese Runde
  Produktion.l ; Ergibt die Aktionspunkte
  Luftwaffe.l ; Anzahl der Flieger
  Heer.l ; Anzahl der Truppen
  Land.l ; Landgrösse
  Victim.l ; = -1, wenn niemand angegriffen werden soll, ansonsten die Spielernummer
  Victim_davor.l ; speichert das Ziel der letzten Runde, wenn keines, dann -1
EndStructure

Dim player.ply(#MAX_CLIENTS)

Global Runde.l ; die neue Runde, die die Spieler gerade bearbeiten
Global StartSpiel.l ; = 1, wenn das Spiel gestartet werden soll

Dim Client.l(#MAX_CLIENTS) ; Die Verbindungsdaten für die Clients
Dim Daten.l(#MAX_CLIENTS) ; = 1, wenn die Daten dieser Runde vom Spieler eingegangen sind
;}

;{- Proceduren
; Core
Procedure ArraySize(*Array) 
  ProcedureReturn PeekL(*Array-8) 
EndProcedure

Procedure Init_Game()
  ; erstellt ein neues Spiel
  Runde = 1
  
  Dim Daten.l(#MAX_CLIENTS) ; alle Eingangsflag auf 0 setzen
  
  For x = 0 To #MAX_CLIENTS
    If Client(x)
      player(x)\Aktiv = 1 ; =1, wenn Spieler aktiv
    Else
      player(x)\Aktiv = 0
    EndIf
    player(x)\Runde = Runde ; Rundennummer
    player(x)\Produktion = 2 ; Ergibt die Aktionspunkte
    player(x)\Aktionspunkte = player(x)\Produktion
    player(x)\Luftwaffe = 0 ; Anzahl der Flieger
    player(x)\Heer = 0 ; Anzahl der Truppen
    player(x)\Land = 10 ; Landgrösse
    player(x)\Victim = -1
    player(x)\Victim_davor = -1
  Next
  Debug "init game"
EndProcedure
Procedure Rundenauswertung()
  ; wertet die Runde aus und sendet die neuen Daten an alle Spieler
  Runde + 1
  PrintN("Werte Runde: " + Str(Runde) + " aus")
  For x = 0 To #MAX_CLIENTS
    ; Nicht versorgte Armeeteile abbauen - d.h. Nach einem Kampf kann die Armee in der nächsten Runde noch einmal kämpfen
    While player(x)\Produktion < player(x)\Luftwaffe + player(x)\Heer
      If player(x)\Luftwaffe + player(x)\Heer - player(x)\Produktion > 2
        player(x)\Luftwaffe - 1
        player(x)\Heer - 1
      Else
        player(x)\Luftwaffe - 1
      EndIf
    Wend
    
    ; kämpfe auswerten
    Beute.l = 0
    If player(x)\Victim > -1 ; wenn Krieg geführt werden soll
      v.l = player(x)\Victim ; Opfervar
      ;{ Luftwaffe
      If player(x)\Luftwaffe > player(v)\Luftwaffe
        diff = player(x)\Luftwaffe - player(v)\Luftwaffe
        player(v)\Produktion = player(v)\Produktion - diff ; Zerstörung der Produktion
        If player(v)\Produktion < 0
          player(v)\Produktion = 0
        EndIf
        ; Verluste
        If dif < 2 ; mindestens 1
          player(x)\Luftwaffe - 1
        Else
          player(x)\Luftwaffe = player(x)\Luftwaffe - diff>>1
        EndIf
        player(v)\Luftwaffe >> 1 ; halbieren
        
      Else
        ; Verluste
        diff = player(v)\Luftwaffe - player(x)\Luftwaffe ; verteidiger > angreifer
        If diff < 2 ; mindestens 1
          player(v)\Luftwaffe - 1
        Else
          player(v)\Luftwaffe  = player(v)\Luftwaffe - diff>>1 
        EndIf
        player(x)\Luftwaffe >> 1 ; halbieren
      EndIf
      ;}
      ;{Heer
      If player(x)\Heer > player(v)\Heer
        Beute = player(x)\Heer - player(v)\Heer
        diff = Beute
        If Beute > player(v)\Land
          Beute = player(v)\Land - 1
        EndIf
        player(v)\Land = player(v)\Land - Beute ; Zerstörung der Produktion
        player(x)\Land = player(x)\Land + Beute
        ; Verluste
        If diff < 2 ; mindestens 1
          player(x)\Heer - 1
        Else
          player(x)\Heer = player(x)\Heer - diff>>1
        EndIf
        player(v)\Heer >> 1 ; halbieren 
      Else
        ; Verluste
        diff = player(v)\Heer - player(x)\Heer ; verteidiger > angreifer
        If diff < 2 ; mindestens 1
          player(v)\Heer - 1 
        Else
          player(v)\Heer  = player(v)\Heer - diff>>1 
        EndIf
        player(x)\Heer >> 1 ; halbieren
      EndIf
      ;}
      If player(v)\Land < player(v)\Produktion
        player(v)\Produktion = player(v)\Land
      EndIf
    EndIf

    
    ; Neue Aktionspunkte setzen
    player(x)\Aktionspunkte = player(x)\Produktion
    If player(x)\Aktionspunkte = 0
      player(x)\Aktionspunkte = 1
    EndIf
    player(x)\Victim_davor = player(x)\Victim
    player(x)\Victim = -1
    player(x)\Runde = Runde
    
  Next
  PrintN("Spiel geht nun in Runde " + Str(Runde))
EndProcedure
Procedure Start_Waiting_Game()
  ; startet das wartende Spiel
  Init_Game() ; Spieldaten für Start setzen
  For y = 0 To #MAX_CLIENTS
    If player(y)\Aktiv
      Msg.s = "ST"
      SendNetworkData(Client(y), @Msg, 2)
      Debug "sende Spielstart an Spielerplatz: " + Str(y) + " / " + Str(Client(y))
      Debug "sende anzahl: " + Str(SizeOf(ply) * ArraySize(@player()))
      SendNetworkData(Client(y), @player(), SizeOf(ply) * ArraySize(@player())); die Daten den Spielrn zusenden
      Debug "sende Spieldaten an Spielerplatz: " + Str(y)
    EndIf
  Next
  PrintN("Spiel gestartet")
EndProcedure
;}

;{- Den Server erstellen
OpenConsole() 
If InitNetwork() = 0 
  PrintN("Das Netzwerksystem konnte nicht gestartet werden")
  PrintN("Das Programm wird in 3 Sekunden beendet")
  If FileSize("ServerParam.txt") > -1
    DeleteFile("ServerParam.txt")
  EndIf
  Delay(3000) 
  End 
EndIf 

If ReadFile(0, "ServerParam.txt")
  cl.s = ReadString()
  Port.l = Val(RTrim(StringField(cl, 1, ", ")))
  SpielName.s = RTrim(StringField(cl, 2, ", "))
  CloseFile(0)
  DeleteFile("ServerParam.txt")
Else
  PrintN("An welchem Port soll der Server lauschen?") 
  Port.l = Val(Input()) 
  PrintN("") 
  PrintN("Geben Sie den Spielnamen an (max. 19 Zeichen)?") 
  SpielName.s =Input()
EndIf
If Len(SpielName) > 19 ; länge des Spielnamens überprüfen
  SpielName = Left(SpielName, 19)
EndIf
If Port < 1000 ; die portnummer überprüfen
  Port = 1000
EndIf
If Port > 7000 
  Port = 7000
EndIf

PrintN("")
PrintN("Starte Spiel " + SpielName + " an Port " + Str(Port))
PrintN("")

If CreateNetworkServer(Port) = 0 
  PrintN("Server konnte nicht erstellt werden") 
  Delay(3000) 
  End 
Else 
  PrintN("Server wurde erstellt")  
EndIf 
;}
;{- Die Aktionsschleife
Repeat 
  Select NetworkServerEvent() 
    Case 1 ;{ a new client has been connected to the server
      t = NetworkClientID()
      c.l = 0
      For x = 0 To #MAX_CLIENTS
        If Client(x) <> 0
          c + 1
        EndIf
      Next
      Msg.s = Str(c) + SpielName
      Msg = Msg + Space(20 - Len(Msg))
      SendNetworkData(t, @Msg, 20) ; sendet die bisherige Spieleranzahl und den SPielnamen
      PrintN("Serveranfrage - ID: " + Str(t))
      ;}
    Case 2  ;{ Raw Data has been received (To be Read with ReceiveNetworkData())
      t = NetworkClientID() ; sender speichern 
      ; testen, ob Sender in Liste eingetragen
      cnt.l = -1 ; nächster freier Platz
      x.l = -1 ; index des Spielers, von dem die Daten kommen
      For y = 0 To #MAX_CLIENTS
        If Client(y) = t
          x = y
        EndIf
        If Client(y) = 0 And cnt = -1
          cnt = y
        EndIf
      Next
      Debug "x: " + Str(x)
      If x > -1 ; wenn schon in der Clientliste
        If StartSpiel = 0
          ; erhalte Spielstart-daten
          Msg = "  "
          ReceiveNetworkData(t, @Msg, 2) ; Daten empfangen
          If Msg = "ST"
            Debug "Code für Spielstart erhalten"
            StartSpiel = 1 ; starte Spiel
            Start_Waiting_Game()
          EndIf
          
        Else 
          Debug "Erhalte Daten von spieler (platz) " + Str(x) + " - verb: " + Str(t)
          Daten(x) = 1 ; die Daten dieses Spielers als erhalten markieren
          ReceiveNetworkData(t, @player(x), SizeOf(ply)) ; ins array schreiben 
          ;{ Checke, ob das der letzte Spieler war
          fertig.l = 1
          For y = 0 To #MAX_CLIENTS
            If player(y)\Aktiv
              If Daten(y) = 0
                fertig = 0 ; noch nicht fertig
              EndIf
            EndIf
          Next
          Debug "fertig: " + Str(fertig)
          ;}
          If fertig ;{ Runde auswerten und Daten zurückschreiben
            Rundenauswertung() 
            For y = 0 To #MAX_CLIENTS ; Daten verschicken und Array zurücksetzen
              If Client(y)
                Debug "§schicke spieler daten für runde " + Str(Runde) + " Spieler: " + Str(y)
                SendNetworkData(Client(y), @player(), SizeOf(ply) * ArraySize(@player()))
                Daten(y) = 0
              EndIf
            Next
            ;}
          EndIf
        EndIf
      Else
        Debug "neuer client sendet daten"
        ; Will sich der Client anmelden?
        Msg.s = " " ; erwarte einen Anmeldestring
        ReceiveNetworkData(t, @Msg, 1)
        Debug "gesendet: " + Msg
        If Msg = "1" ; Anmeldeversuch
          If cnt > -1 ; wenn noch Platz in der Clientliste war
            Client(cnt) = t ; in die Liste aufnehmen
            PrintN("Neuer Client auf platz "  + Str(cnt) + " - NR. " + Str(Client(cnt)))
            Msg.s = "1-" + Str(cnt) 
            SendNetworkData(t, @Msg, 3) ; sende dem Client - Bestätigung Warteliste
            
            ;{ Schicke allen Spielern die Neue Spielerzahl
            Msg.s = Str(cnt+1)
            For y = 0 To #MAX_CLIENTS
              If Client(y)
                SendNetworkData(Client(y), @Msg, 1)
              EndIf
            Next
            ;}
            Debug "bestätigung: Warten verschickt: " + Msg
            If cnt = #MAX_CLIENTS
              ; Maximale Anzahl erreicht
              Debug "alle Spieler da - Spiel sollte hier starten"
              Start_Waiting_Game()
            EndIf
          Else
            PrintN("Neuer Client versuchte sich einzuloggen - kein Platz auf Liste")
            Msg.s = "9-"
            SendNetworkData(t, @Msg, 2) ; sende dem Client - Absage wegen Voll
            Debug "absage geschickt: " + Msg
          EndIf
        EndIf
      EndIf
      ;}
      
    Case 3 ; a file has been received (To be Read with ReceiveNetworkFile())
      
    Case 4 ;{ a client has quit the server (deconnection)
      t = NetworkClientID() ; sender speichern 
      ; testen, ob Sender in Liste eingetragen
      c.l = 0 ;flag für Abmeldung von Spieler
      rest.l = 0
      For x = 0 To #MAX_CLIENTS
        If Client(x) = t
          Client(x) = 0 ; aus der Liste austragen
          PrintN("Client hat sich ausgeloggt - Nr: " + Str(x))
          c + 1 
        EndIf
        If Client(x) <> 0 ; aktiver Spieler
          rest + 1
        EndIf
      Next
      If c ; Schicke allen Spielern die Neue Spielerzahl
        Msg.s = Str(rest)
        For y = 0 To #MAX_CLIENTS
          If Client(y)
            SendNetworkData(Client(y), @Msg, 1)
          EndIf
        Next
      EndIf 
      If rest = 0 And StartSpiel ; keine Spieler mehr
        StartSpiel = 0
        PrintN("Spiel beendet - keine Spieler mehr")
      EndIf
      If c = 0
        PrintN("Ein Anfrager hat sich ausgeloggt - ID: " + Str(t))
      EndIf
      ;}
  EndSelect
  Delay(1)
ForEver 
;}
Der Server muss als "Entscheidungen Server.exe" im gleichen Verzeichnis sein, in dem der Client ist.

Wenns jemand mal ausprobiert, wäre ich über ne Rückmeldung dankbar.

P.S. Ich habe versucht, keine API zu verwenden (das mit dem Exepath ist nur zum debuggen gewesen, kann man rausschmeissen).
Es sollte also auch unter Linux laufen.
Wenn das mal jemand testen könnte und mir was dazu sagen könnte, wäre ich froh.
PMTheQuick
Beiträge: 630
Registriert: 05.05.2005 19:06

Beitrag von PMTheQuick »

Es funktioniert bei mir. Ich habe Windows XP Home Edition. Aber, was ist der Sinn der Sache? :?

Pascal :lol:
Benutzeravatar
Dostej
Beiträge: 529
Registriert: 01.10.2004 10:02
Kontaktdaten:

Beitrag von Dostej »

Wie gesagt, es macht nur sinn, wenn es 2 zusammen spielen. Evtl. mehrmals. Das zeigt interessante Dinge im Umgang mit (evtl.) Konfliktsituatiionen
Antworten