インターネットを使ったゲームについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
COOP

インターネットを使ったゲームについて

#1

投稿記事 by COOP » 6年前

初めまして。
大学の講義で4人麻雀を作ることになったのですがインターネットを使った対戦の実装の方法が全くわかりません。今までにインターネットを使ったデータの受け渡しを行ったことがなく、また4台のパソコンでの通信ということもあり何をしたらいいかがわからない状態です。アドバイス、参考になるサイトなどを教えてもらいたいと思い書きこみをしました。
今のところ同一LAN内限定での対戦を考えています。

また、自分なりに模索して2台のパソコンを通信させることに成功しましたがこれでいいのかどうかがわかりません。http://homepage2.nifty.com/natupaji/DxL ... ればいいのでしょうか

OSはwindows7,コンパイラはVC++2008,ライブラリはDXライブラリを使っています。
C言語は2年ほど講義でやっただけです。参考になるかはわかりませんがコマンドプロンプト上で動く簡単なテトリスを作ったことがあります。

URLの方にものってますがこっちにもソースコードをのせておきます。これを使って2台通信させることに成功しました。
これを応用すれば4台でデータの受け渡しができるのでしょうか?

接続側プログラム

コード:

#include "DxLib.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
			 LPSTR lpCmdLine, int nCmdShow )
{
	char StrBuf[ 256 ] ;	// データバッファ
	IPDATA Ip ;		// 接続用IPアドレスデータ
	int NetHandle ;		// ネットワークハンドル
	int DataLength ;		// 受信データ量保存用変数

	if( DxLib_Init() == -1 )	// DXライブラリ初期化処理
	{
		 return -1;	// エラーが起きたら直ちに終了
	}

	// IPアドレスを設定( ここにある4つのIP値は仮です )
	Ip.d1 = **;
	Ip.d2 = **;
	Ip.d3 = **;
	Ip.d4 = **;

	// 通信を確立
	NetHandle = ConnectNetWork( Ip, 9850 ) ;

	// 確立が成功した場合のみ中の処理をする
	if( NetHandle != -1 )
	{ 
		// データ送信
		NetWorkSend( NetHandle , "繋がったか~!?" , 17 ) ;

		// データがくるのを待つ
		while( !ProcessMessage() )
		{
			// 取得していない受信データ量を得る
			DataLength = GetNetWorkDataLength( NetHandle ) ;

			// 取得してない受信データ量が0じゃない場合はループを抜ける
			if( DataLength != 0 ) break ;
		}

		// データ受信
		NetWorkRecv( NetHandle , StrBuf , DataLength ) ;	// データをバッファに取得

		// 受信したデータを描画
		DrawString( 0 , 0 , StrBuf , GetColor( 255 , 255 , 255 ) ) ;

		// キー入力待ち
		WaitKey() ;

		// 接続を断つ
		CloseNetWork( NetHandle ) ;
	}

	DxLib_End() ;	// DXライブラリ使用の終了処理

	return 0 ;	// ソフトの終了
}

接続待ち側プログラム

コード:

#include "DxLib.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
			LPSTR lpCmdLine, int nCmdShow )
{
	char StrBuf[ 256 ] ;		// データバッファ
	int NetHandle , LostHandle ;	// ネットワークハンドル
	int DataLength ;			// 受信データ量保存用変数
	IPDATA Ip ;			// 接続先IPアドレスデータ

	if( DxLib_Init() == -1 )	// DXライブラリ初期化処理
	{
		return -1;	// エラーが起きたら直ちに終了
	}

	// 接続してくるのを待つ状態にする
	PreparationListenNetWork( 9850 ) ;

	// 接続してくるかESCキーが押されるまでループ
	NetHandle = -1 ;
	while( !ProcessMessage() && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
	{
		// 新しい接続があったらそのネットワークハンドルを得る
		NetHandle = GetNewAcceptNetWork() ;
		if( NetHandle != -1 ) break ;
	}

	// 接続されていたら次に進む
	if( NetHandle != -1 )
	{
		// 接続の受付を終了する
		StopListenNetWork() ;

		// 接続してきたマシンのIPアドレスを得る
		GetNetWorkIP( NetHandle , &Ip ) ;

		// データが送られて来るまで待つ
		while( !ProcessMessage() )
		{
			// 取得していない受信データ量が0以外のときはループから抜ける
			if( GetNetWorkDataLength( NetHandle ) != 0 ) break ;
		}

		// データ受信
		DataLength = GetNetWorkDataLength( NetHandle ) ;	// データの量を取得
		NetWorkRecv( NetHandle , StrBuf , DataLength );	// データをバッファに取得

		// 受信したデータを描画
		DrawString( 0 , 0 , StrBuf , GetColor( 255 , 255 , 255 ) ) ;

		// 受信成功のデータを送信
		NetWorkSend( NetHandle , "繋がったぞ~!!" , 17 ) ;

		// 相手が通信を切断するまで待つ
		while( !ProcessMessage() )
		{
			// 新たに切断されたネットワークハンドルを得る
			LostHandle = GetLostNetWork() ;

			// 切断された接続が今まで通信してた相手だった場合ループを抜ける
			if( LostHandle == NetHandle ) break ;
		}

		// 切断確認表示
		DrawString( 0 , 16 , "切断しました" , GetColor( 255 , 255 , 255 ) ) ;

		// キー入力待ち
		WaitKey() ;
	}

	DxLib_End() ;	// DXライブラリ使用の終了処理

	return 0 ;	// ソフトの終了
}

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: インターネットを使ったゲームについて

#2

投稿記事 by h2so5 » 6年前

よくある構成としては、4台のマシンのうち1台をホストにして他の3台がそのホストに接続するというものがあります。
麻雀のゲームの進行状況はホストが集中的に管理します。

jay
記事: 314
登録日時: 9年前
住所: 大阪市
連絡を取る:

Re: インターネットを使ったゲームについて

#3

投稿記事 by jay » 6年前

h2so5さんの回答に補足…、と言うかもう少し具体的に書きますと

4台の内1台をホストに定めます
あとの3台はクライアントとして処理します

例えばクライアントAが何か牌を切ったら、「この牌を切った」とホストに伝えます。
ホストは「Aがこの牌を切った」とクライアントBとCに伝えるわけですね。

後はAが牌を切る処理を各々が行い、ホスト+3台のクライアント全てが
「Aが牌を切る処理を行った」とホストに伝えたら(=フラグを立てたら)
次はホストがBに「お前の手番だ」と伝える、という流れですね
Bが処理を行っている間他のクライアントは待機、ホストはBの処理を受け取る準備をしておきます。


大事なのはホスト+3台のクライアント全てが「Aが牌を切る処理を行った」とホストに伝えたら
という部分です。
俗にいう”同期処理”というヤツですが
これをやらないと”同期ズレ”という現象が起きちゃいます。

どういうタイミングで同期させるかはゲームの性質によって大きく違ってきますので
ご自分で考えてみてくださいね。
♪僕たちは まだ森の中 抜け出そう 陽のあたる場所へ

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: インターネットを使ったゲームについて

#4

投稿記事 by h2so5 » 6年前

jayさんの回答に補足です。

クライアント側では牌の処理を一切せず、ホストで全部処理してその結果をクライアントが受信して表示するだけにした方が簡単だと思います。
つまり、ホストはゲームの状態が変化するたびに現在の状態をすべてクライアントに送信します。CGIで実装されている対戦麻雀などと似たような感じです。

こうするとトラフィックは増えますが同期ズレを気にする必要がなくなります。LANですし、大したデータ量でもないので問題はないでしょう。

COOP

Re: インターネットを使ったゲームについて

#5

投稿記事 by COOP » 6年前

返信遅くなりました。すいません。
回答ありがとうございます。お二方のアドバイスを参考にホスト1台+クライアント3台でつくることにしました。
また、いきなり4人麻雀を作るのも大変なのでまずは2人麻雀を作り、完成したら4人麻雀を作る方針にしました。
そういえば同期ズレのことまでは考えていませんでした・・・ホストで牌の処理を行うことにします。

そこでまた質問なのですがデータの受け渡しは上で示したプログラムでいいのでしょうか?
もちろん今のままでは数字の受け渡しはできていないので多少なりとも変える必要はあると思いますが・・・
このプログラムで数字の受け渡しをできるようにして麻雀プログラムに組み込もうと考えていますがこれであっているのでしょうか?
何せ時間が限られているので遠回りであったりもう少し簡単な方法があるならぜひ教えていただきたいです。

返信が遅れてしまったのでまだ見てくれている人がいるかわかりませんがぜひよろしくお願いします。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: インターネットを使ったゲームについて

#6

投稿記事 by softya(ソフト屋) » 6年前

簡単にしたい場合は数値に関しては文字列で受け渡せば良いと思いますが、今のままの構造だとゲームプログラムには成らないですよね。

ここのチャットを参考にされては? これもエレガントとはいえないですが。 → プレイ中の接続とか切断ができない。
「DXライブラリ置き場 サンプルプログラム」
http://homepage2.nifty.com/natupaji/DxL ... m.html#N21
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

COOP

Re: インターネットを使ったゲームについて

#7

投稿記事 by COOP » 6年前

ありがとうございます。参考にさせていただきます。

みなさんの意見を参考に試行錯誤してみたいと思います。また、何か問題が発生もしくはゲームが完成したらここに書き込みたいと思います。

閉鎖

“C言語何でも質問掲示板” へ戻る