Eu fiz aqui, um joguinho em C#, a pessoa deve simplesmente adivinhar números. Só que Online. Só criar um jogo. Quem acertar o número primeiro, ganha. Queria que avaliassem meu código. Se possível, pode pegar o cliente e jogar o joguinho comigo. Conecte pelo seguinte IP: "201.35.216.220". (Download: http://www.easy-share.com/[telefone removido]/AdivinhaOnline.exe)
Uma outra coisa, o jogo está usando RTF para mostrar mensagens coloridas. E a API do Windows (ARGH!) pra fazer AutoScroll. Aí que a portabilidade vai pro saco. (Existe Mono.). Existe uma alternativa melhor?
Segue o código do Servidor.
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
namespace Server
{
class User
{
public TcpClient conn = null;
public string name = "Anônimo";
public string ip;
public NetworkStream ns;
public StreamWriter w;
public StreamReader r;
public int tent = 0;
public int win = 0;
public User(TcpClient conn)
{
this.conn = conn;
this.ns = this.conn.GetStream();
this.r = new StreamReader(this.ns);
this.w = new StreamWriter(this.ns);
}
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}
}
class Program
{
static TcpListener server = new TcpListener(IPAddress.Any, 8080);
static TcpClient a;
static List<User> users = new List<User>();
static User user;
static string userlist;
static int maxnum;
static int rnum;
static bool ingame = false;
static string gameuser;
static void Main(string[] args)
{
Console.WriteLine("Starting server...");
server.Start();
Console.WriteLine("Server Up! Listening...");
while (true)
{
a = server.AcceptTcpClient();
user = new User(a);
user.ip = ((IPEndPoint)a.Client.RemoteEndPoint).Address.ToString();
Console.WriteLine("Connection from: {0}", user.ip);
new Thread(new ParameterizedThreadStart(Serve)).Start(user);
}
}
static void Broadcast(List<User> users, string str)
{
foreach (User i in users)
{
i.w.WriteLine(str);
i.w.Flush();
}
}
static void UpdateUserList()
{
userlist = String.Join("|", users.Select(x => String.Format("{0} - {1} ({2})", x.name, x.win, x.tent)).ToArray<string>());
Broadcast(users, "UPDATE " + userlist);
}
static void Serve(Object usr)
{
User user = (User)usr;
users.Add(user);
int id = users.Count - 1;
user.w.WriteLine("HELLO");
user.w.WriteLine("IDENTIFY");
user.w.Flush();
while (true)
{
try
{
string cmd = user.r.ReadLine();
Console.WriteLine("Recieved \"{0}\" from {1}", cmd, user.ip);
string[] cmd2 = cmd.Split();
if (cmd2[0] == "USER")
{
string usern = cmd.Substring(5, cmd.Length - 5);
user.name = usern;
users[id].name = usern;
UpdateUserList(); // Usuario entrou, update
Broadcast(users, String.Format("DISPLAY \\cf2\"{0}\" entrou na sala!\\cf0", user.name));
if (ingame)
{
user.w.WriteLine(String.Format("DISPLAY \\b Você entrou no meio do jogo de \"{0}\"\\b0", gameuser));
user.w.WriteLine(String.Format("DISPLAY \\b Adivinhe um número de 1 até {0}!\\b0", maxnum));
user.w.WriteLine("INGAME");
user.w.Flush();
}
}
else if (cmd2[0] == "SAY")
{
Broadcast(users, String.Format("DISPLAY2 \\b<{0}>\\b0 {1}", user.name, cmd.Substring(4, cmd.Length - 4)));
}
else if (cmd2[0] == "STARTGAME")
{
if (ingame)
{
user.w.WriteLine("DISPLAY \\b\\cf1Um jogo já foi iniciado.\\cf0\\b0");
user.w.Flush();
}
else
{
bool valid = Int32.TryParse(cmd2[1], out maxnum);
if (valid && maxnum > 1)
{
ingame = true;
gameuser = user.name;
rnum = new Random().Next(1, maxnum);
Broadcast(users, "INGAME");
Broadcast(users, String.Format("DISPLAY \\b Usuário \"{0}\" criou um jogo.\\b0", gameuser));
Broadcast(users, String.Format("DISPLAY \\b Adivinhe um número de 1 até {0}!\\b0", maxnum));
}
else
{
user.w.WriteLine("DISPLAY \\b\\cf1Entre com um número válido!\\cf0\\b0");
user.w.Flush();
}
}
}
else if (cmd2[0] == "TRY")
{
if (ingame)
{
int ttt;
bool valid = Int32.TryParse(cmd2[1], out ttt);
if (valid && ttt >= 1 && ttt <= maxnum)
{
user.tent++;
if (ttt > rnum)
{
user.w.WriteLine("DISPLAY O número é menor!");
user.w.Flush();
}
else if (ttt < rnum)
{
user.w.WriteLine("DISPLAY O número é maior!");
user.w.Flush();
}
else
{
Broadcast(users, "ENDGAME");
Broadcast(users, String.Format("DISPLAY \\b\\cf2\"{0}\" ganhou com {1} tentativas! O número era {2}!\\cf0\\b0", user.name, user.tent, rnum));
user.win += 1;
user.tent = 0;
users[id].tent = 0;
foreach (User i in users)
{
i.tent = 0;
}
ingame = false;
}
UpdateUserList(); //Usuario tentou, update.
}
else
{
user.w.WriteLine("DISPLAY \\b\\cf1Entre com um número válido!\\cf0\\b0");
user.w.Flush();
}
}
else
{
user.w.WriteLine("DISPLAY \\b\\cf1Crie um jogo primeiro.\\cf0\\b0");
user.w.Flush();
}
}
else
{
user.w.WriteLine("UNIMPL");
user.w.Flush();
}
}
catch
{
break;
}
}
users.Remove(user);
UpdateUserList(); //Usuario saiu, update.
Console.WriteLine("Connection from {0} closed.", user.ip);
Broadcast(users, String.Format("DISPLAY \\cf1\"{0}\" saiu da sala!\\cf0", user.name));
user.conn.Close();
}
}
}
E aqui, o código do cliente:
using System;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
namespace Client
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
TcpClient cl;
NetworkStream ns;
StreamReader r;
StreamWriter w;
string text1;
string text2;
private void button1_Click(object sender, EventArgs e)
{
cl = new TcpClient();
cl.Connect(textBox7.Text, 8080);
ns = cl.GetStream();
r = new StreamReader(ns);
w = new StreamWriter(ns);
r.ReadLine();
r.ReadLine();
w.WriteLine("USER " + textBox1.Text);
w.Flush();
backgroundWorker1.RunWorkerAsync();
groupBox1.Enabled = true;
groupBox2.Enabled = false;
groupBox3.Enabled = true;
groupBox4.Enabled = true;
groupBox5.Enabled = true;
}
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
while (true)
{
string cmd = r.ReadLine();
string[] cmd2 = cmd.Split();
if (cmd2[0] == "INGAME")
{
groupBox3.Enabled = false;
button3.Enabled = true;
}
else if (cmd2[0] == "ENDGAME")
{
groupBox3.Enabled = true;
button3.Enabled = false;
}
else if (cmd2[0] == "UPDATE")
{
listBox1.Items.Clear();
string users = cmd.Substring(7, cmd.Length - 7);
foreach (string i in users.Split('|'))
{
listBox1.Items.Add(i);
}
}
else if (cmd2[0] == "DISPLAY")
{
text1 += cmd.Substring(8, cmd.Length - 8) + "\\par\n";
richTextBox1.Rtf = "{\\rtf1 {\\colortbl;\\red255\\green0\\blue0;\\red0\\green176\\blue80;}" + text1 + "}";
}
else if (cmd2[0] == "DISPLAY2")
{
text2 += cmd.Substring(8, cmd.Length - 8) + "\\par\n";
richTextBox2.Rtf = "{\\rtf1 " + text2 + "}";
}
}
}
private void button2_Click(object sender, EventArgs e)
{
int dif;
if (Int32.TryParse(textBox2.Text, out dif))
{
w.WriteLine("STARTGAME " + textBox2.Text);
w.Flush();
}
else
{
MessageBox.Show("Entre com um número!", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void button3_Click(object sender, EventArgs e)
{
int tent;
if (Int32.TryParse(textBox3.Text, out tent))
{
w.WriteLine("TRY " + textBox3.Text);
w.Flush();
}
else if (textBox3.Text.Trim() == String.Empty)
{
}
else
{
MessageBox.Show("Entre com um número!", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
textBox3.Clear();
AcceptButton = button3;
}
private void button4_Click(object sender, EventArgs e)
{
if (!(textBox4.Text.Trim() == String.Empty))
{
w.WriteLine("SAY " + textBox4.Text);
w.Flush();
}
else
{
}
textBox4.Clear();
AcceptButton = button4;
}
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
const int WM_VSCROLL = 277;
const int SB_BOTTOM = 7;
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
SendMessage(richTextBox1.Handle, WM_VSCROLL, new IntPtr(SB_BOTTOM), IntPtr.Zero);
}
private void richTextBox2_TextChanged(object sender, EventArgs e)
{
SendMessage(richTextBox2.Handle, WM_VSCROLL, new IntPtr(SB_BOTTOM), IntPtr.Zero);
}
}
}
Pra quem quiser ver o joguinho funcionando:
[img]http://img56.imageshack.us/img56/1677/capturag.png[/img]
Alguma sugestão para melhorar meu código?