Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 26-09-2024
navbuoy navbuoy is offline
Miembro
 
Registrado: mar 2024
Posts: 280
Poder: 2
navbuoy Va por buen camino
Stardust IA Daemon - Codigo fuente




Este programa, lo estoy haciendo con la finalidad de que o bien corra en un PC dedicado todo el tiempo (dia y noche 365 dias al año) en mi casa o bien podria ser un VPS Windows ahi cargado en el VPS y funcionando (seria lo ideal pero muy caro sobre todo teniendo en cuenta que aun no ha entrado ni un solo euro en Donaciones a Stardust)

tambien tener en cuenta que para que cumpla su funcion lo del boton Start Daemon lo que tendria que hacer es un Temporizador en base al tiempo entre movimientos de todas las fichas cada X segundos o tal
eso supongo que ya os lo habreis imaginado para que este siempre haciendo la tarea...

a lo que iba, este "demonio" aunque muy poco desarrollado y de manera chapucera, lo que hace es obtener en un TQuery, un listado de una serie de items de la Tabla en MySQL donde se almacenan las naves y tal (las naves estan definidas del 2 al 10 y el 15 y el 20 (como valores enteros en la tabla) indican que son naves de la IA del juego

owner representa el propietario que en este caso el numero 7 es la propia IA de Stardust

cuando cliqueamos en Start Daemon solo inicia un filtrado de esas naves y owner y luego con TQuery2 efectua el UPDATE teniendo en cuenta si la celda a donde quiere mover la nave esta vacia (a cero) o no, el movimiento es algo "chapucero" ya que unicamente es un movimiento lineal hacia delante o hacia atras en los registros que conforman el tablero de 18.000 celdas y poco mas, si por ejemplo la celda esta ocupada por algun otro "inquilino" va restando el numero de movimiento hasta que encuentra una celda libre y si no la encuentra pues pega el JUMP salto y se olvida de moverla ya que no ha podido o lo que sea


os pongo el codigo fuente de la app por si os sirve de ayuda (uso los componentes MyDAC MySQL y los Alpha Controls para el skin del interface)
tambien utiliza el componente TIconTray para minimizar a la bandeja de iconos de sistema y ocultar la app



Fichero unit1.h


Código:
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
#include "DBAccess.hpp"
#include "MemDS.hpp"
#include "MyAccess.hpp"
#include <Data.DB.hpp>
#include "sPageControl.hpp"
#include "sSkinManager.hpp"
#include <Vcl.ComCtrls.hpp>
#include "sButton.hpp"
#include "sEdit.hpp"
#include "sLabel.hpp"
#include "acImage.hpp"
#include "acPNG.hpp"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE-managed Components
	TTrayIcon *TrayIcon1;
	TsPageControl *sPageControl1;
	TsTabSheet *sTabSheet1;
	TButton *Button1;
	TMemo *Memo1;
	TEdit *Edit1;
	TLabel *Label1;
	TsSkinManager *sSkinManager1;
	TsTabSheet *sTabSheet2;
	TMyConnection *MyConnection1;
	TMyTable *MyTable_DevLog;
	TMyConnection *MyConnection2;
	TMyQuery *MyQuery1;
	TsButton *sButton1;
	TsImage *sImage1;
	TsLabel *sLabel7;
	TsEdit *sEdit5;
	TsLabel *sLabel6;
	TsEdit *sEdit1;
	TsLabel *sLabel1;
	TsEdit *sEdit4;
	TsEdit *sEdit3;
	TsEdit *sEdit2;
	TsLabel *sLabel4;
	TsLabel *sLabel3;
	TsLabel *sLabel2;
	TsLabel *sLabel5;
	TsButton *sButton2;
	TMyQuery *MyQuery2;
	void __fastcall FormResize(TObject *Sender);
	void __fastcall TrayIcon1Click(TObject *Sender);
	void __fastcall sButton1Click(TObject *Sender);
private:	// User declarations
public:		// User declarations
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif


Fichero Unit1.cpp

Código:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "DBAccess"
#pragma link "MemDS"
#pragma link "MyAccess"
#pragma link "sPageControl"
#pragma link "sSkinManager"
#pragma link "sButton"
#pragma link "sEdit"
#pragma link "sLabel"
#pragma link "acImage"
#pragma link "acPNG"
#pragma resource "*.dfm"
TForm1 *Form1;

const int TOTAL_CELDAS = 18000;  // Total de celdas en la base de datos
struct { float id; bool flag; int icon; int owner; int energylevel; int faction; int FIELDACTUAL; int id_nave; int Clan;} celda;

long int BUSCA_CELDA_LIBRE(long int id_ORIGEN);

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
	  if (Form1->WindowState == wsMinimized)
	{
		// Oculta la ventana principal
		Application->ShowMainForm = false;
		// Ocultar la ventana principal (desaparece de la barra de tareas)
		ShowWindow(Handle, SW_HIDE);
		// Muestra el ícono en la bandeja del sistema
		TrayIcon1->Visible = true;
		TrayIcon1->BalloonHint = "La aplicación se ha minimizado a la bandeja del sistema";
		TrayIcon1->BalloonTitle = "Aplicación Minimizada";
		TrayIcon1->ShowBalloonHint();
	}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::TrayIcon1Click(TObject *Sender)
{
	  // Restaura la ventana principal
	Application->ShowMainForm = true;
	WindowState = wsNormal;
	Form1->Show();
	// Traer la ventana al frente
	SetForegroundWindow(Handle);
	// Oculta el ícono de la bandeja
	TrayIcon1->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::sButton1Click(TObject *Sender)
{
  float resultado = 0;
  float celda_ocupada = 0;

  Form1->MyQuery1->SQL->Clear();
  Form1->MyQuery1->SQL->Add("SELECT * ");
  Form1->MyQuery1->SQL->Add("FROM CELDAS_TABLERO WHERE owner = 7 AND icon = 15 OR icon = 20 AND icon BETWEEN 2 AND 10");
  Form1->MyQuery1->ExecSQL();

  sEdit5->Text = Form1->MyQuery1->RecordCount;

  Form1->MyQuery1->First();

  for(int c=0; c < Form1->MyQuery1->RecordCount; ++c)
   {

	 celda.id = Form1->MyQuery1->FieldByName("id")->AsInteger;
	 celda.flag = Form1->MyQuery1->FieldByName("flag")->AsInteger;
	 celda.icon = Form1->MyQuery1->FieldByName("icon")->AsInteger;
	 celda.owner = Form1->MyQuery1->FieldByName("owner")->AsInteger;
	 celda.energylevel = Form1->MyQuery1->FieldByName("energylevel")->AsInteger;
	 celda.faction = Form1->MyQuery1->FieldByName("faction")->AsInteger;
	 celda.FIELDACTUAL = Form1->MyQuery1->FieldByName("FIELDACTUAL")->AsInteger;
	 celda.id_nave = Form1->MyQuery1->FieldByName("id_nave")->AsInteger;
	 celda.Clan = Form1->MyQuery1->FieldByName("Clan")->AsInteger;

	 resultado = BUSCA_CELDA_LIBRE(Form1->MyQuery1->FieldByName("id")->AsInteger);

	 if(resultado <= 0) goto JUMP;

	 else {

			 //Borramos la celda id de origen (puesta a 0)
			 Form1->MyQuery2->SQL->Clear();
			 Form1->MyQuery2->SQL->Add("UPDATE CELDAS_TABLERO WHERE id = " + IntToStr(Form1->MyQuery1->FieldByName("id")->AsInteger) + " SET flag = 0, icon = 0, owner = 0, energylevel = 0, faction = 0, FIELDACTUAL = 0, id_nave = 0, Clan = 0");
			 Form1->MyQuery2->ExecSQL();

	         //Movemos la nave a su nueva id de posicion
			 Form1->MyQuery2->SQL->Clear();
			 Form1->MyQuery2->SQL->Add("UPDATE CELDAS_TABLERO WHERE id = " + FloatToStr(resultado) + " SET flag = " + IntToStr(celda.flag) + ", icon = " + IntToStr(celda.icon) + ", owner = " + IntToStr(celda.owner) + ", energylevel = " + IntToStr(celda.energylevel) + ", faction = " + IntToStr(celda.faction) + ", FIELDACTUAL = " + IntToStr(celda.FIELDACTUAL) + ", id_nave = " + IntToStr(celda.id_nave) + ", Clan = " + IntToStr(celda.Clan) + ";");
			 Form1->MyQuery2->ExecSQL();

		   }



	JUMP:

	Form1->MyQuery1->Next();
	sEdit1->Text = c;

   }
}
//---------------------------------------------------------------------------
long int BUSCA_CELDA_LIBRE(long int id_ORIGEN)
 {

  int num_movimientos = 0;
  bool direccion = 0;


  num_movimientos = rand() % 10;
  direccion = rand() % 2;

  if(direccion == 1)
  {
	if(id_ORIGEN + num_movimientos > TOTAL_CELDAS) num_movimientos = TOTAL_CELDAS - id_ORIGEN;
  }

  else if(direccion == 0)
   {
	if(id_ORIGEN - num_movimientos < 0) num_movimientos = 0 + num_movimientos;
   }




	 Form1->MyQuery2->SQL->Clear();
	 Form1->MyQuery2->SQL->Add("SELECT * ");
	 Form1->MyQuery2->SQL->Add("FROM CELDAS_TABLERO WHERE id > " + FloatToStr(id_ORIGEN - 20) + " AND " + "id < " + FloatToStr(id_ORIGEN + 20));
	 Form1->MyQuery2->ExecSQL();


 while(num_movimientos > 0)
	 {
		 if(direccion == 1)
		  {
			Form1->MyQuery2->MoveBy(0 + 21 + num_movimientos);
		   }

		 else if(direccion == 0)
		  {
			 Form1->MyQuery2->MoveBy(0 + 21 - num_movimientos);
			}

		if(Form1->MyQuery2->FieldByName("owner")->AsInteger == 0 && Form1->MyQuery1->FieldByName("icon")->AsInteger == 0)
		  {
			return(Form1->MyQuery2->FieldByName("id")->AsInteger);
		  }

		else {


				num_movimientos--;
				if(num_movimientos == 0) return(0);
				Form1->MyQuery2->Next();

			  }


	 }

  return(0);
 }

Última edición por navbuoy fecha: 26-09-2024 a las 12:11:16.
Responder Con Cita
  #2  
Antiguo 02-10-2024
navbuoy navbuoy is offline
Miembro
 
Registrado: mar 2024
Posts: 280
Poder: 2
navbuoy Va por buen camino
he modificado un poco el interface y le he añadido lo de controlar y actualizar el numero de jugadores conectados



el numero de jugadores conectados lo controla con el Daemon este pero tambien me las he ingeniado para hacer un STORED PROCEDURE que llamo desde CRON del Hosting cada 15 minutos para actualizar en la pagina web el numero de jugadores conectados y el estado operativo del servidor MySQL

el codigo del stored procedure es este:

Código:
DELIMITER $$

USE `AQUI_LA_BD`$$

DROP PROCEDURE IF EXISTS `Stardust_Players_Conected`$$

CREATE DEFINER=`NOMBRE_USUARIO_DE_LA_BD`@`%` PROCEDURE `Stardust_Players_Conected`()
BEGIN
    DECLARE suma_total DECIMAL(10, 0);
    -- Sumar los valores de campo_a_sumar cuando condicion_campo es 1
    SELECT COALESCE(SUM(status_online), 0) INTO suma_total
    FROM AQUI_NOMBRE_DE_LA_TABLA
    WHERE status_online = 1;
    -- Insertar el resultado en la tabla donde tenemos el numero de jugadores conectados (yo solo tengo 3 campos ID, NUMERO_JUGADORES y Fecha)
    TRUNCATE TABLE AQUI_NOMBRE_DE_OTRA_TABLA_CON_1_SOLO_REGISTRO_DONDE_GUARDARA_EL_NUMERO_DE_PLAYERS;
    INSERT INTO NOMBRE_TABLA (AQUI_CAMPO_INT_DE_NUMERO_DE_PLAYERS, Fecha)
    VALUES (suma_total, CURDATE());
    END$$

DELIMITER ;
son 2 tablas, en la primera, es donde almacena un campo bool (status_online se llama) que es 0 si no esta conectado el usuario o 1 si esta conectado
esto tenemos que controlarlo en el EXE cuando se loguean o se desconectan o cierra el programa actualizar ese campo a 0 en caso de cerrar o desconectarse o a 1 si se loguean bien (password correcto etc)

de esa manera con esta linea:

Código:
SELECT COALESCE(SUM(status_online), 0) INTO suma_total
    FROM AQUI_NOMBRE_DE_LA_TABLA
    WHERE status_online = 1;
sumamos todos los que esten a 1 (conectados online)

de esta forma en la pagina PHP en la web, facilmente con una conexion a la Tabla de PLAYERS_CONECTADOS_TOTALES podemos facilmente
tener un contador en tiempo mas o menos real cada 15 minutos de los jugadores online que hay en el juego

aqui podemos verlo en la web de Stardust


Última edición por navbuoy fecha: 02-10-2024 a las 17:07:24.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Codigo fuente carloseh La Taberna 5 29-05-2013 18:18:17
crear servicio(daemon) en lazarus n03l Lazarus, FreePascal, Kylix, etc. 7 20-06-2012 18:11:41
Código fuente chinchan C++ Builder 3 01-08-2006 04:59:25
TPV.- Codigo Fuente Rabata Varios 4 15-10-2005 13:48:51


La franja horaria es GMT +2. Ahora son las 16:15:35.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi