Pythonのソケット通信で対戦ゲームを作る|小中学生と半年かけて動かした記録
2台のパソコンをつないで、対戦できるゲームを作る。Pythonのsocketモジュールを使えば、これは実現できます。
太子プログラミングクラブ中級コースで、2026年2月から7月までの半年をかけて、小中学生のメンバーとこれに取り組みました。この記事は、そのときの手順と、途中で引っかかったところをまとめたものです。

はじめて2台がつながって、それぞれの画面で自分と相手の機体が動いたとき、「おおーっ」と歓声が上がりました。あの瞬間のために、ここまでの手順があると言ってもいいと思います。
この記事で作るもの
作るのは、シューティングゲームの通信対戦版です。同じネットワークにつながった2台のパソコンで、片方をサーバー、もう片方をクライアントとして起動し、お互いの機体の位置や弾の情報をやり取りします。
用意するものは、次の3つです。
- Pythonが動くパソコン2台(Windows+Linuxで進めました)
- 2台が同じネットワークにつながっていること(ここが後半の山場です)
- 標準ライブラリのsocketとthreading。追加のインストールは要りません
クラブで使った完成コードは、GitHubに置いてあります。この記事では、それぞれのファイルが何をしているかを順に説明していきます。
まずはIPアドレスとポートを確認する
パソコン同士で通信するには、相手がどこにいるのかが分からないと始まりません。最初にやるのは、自分のパソコンのIPアドレスを調べることです。
黒い画面でコマンドを打つ
Windowsであれば、コマンドプロンプトで ipconfig を実行します。ついでに hostname も打たせて、自分のパソコンには名前がついていることも確認しておきます。

小学生のメンバーにも、黒い画面でゴリゴリとコマンドを打たせます。子ども向けに作られた出来合いの教材ではなく、世の中の普通のツールをそのまま使ってもらう。これは私たちのクラブの方針です。しんどいところもありますが、実際に使えてなんぼの世界ですから。

TCP/IPは「なんとなく概要を掴む」で十分
IPアドレスを確認したついでに、TCP/IP通信の仕組みもごく簡単に説明しました。ただし、詳しい通信仕様はどうでもいいので、まずはなんとなく概要を掴むことが大切です。ここで正確さを求めると、動かす前に力尽きます。
続いてポート番号の設定です。今回は12345番を使いました。使われていない番号であれば何番でも構いませんが、2台で同じ番号を指定する必要があります。
一方向にメッセージを送ってみる
いきなりゲームに手をつけず、まずは文字を1回送るだけのプログラムから始めます。
ここで出てくるのが、サーバー側とクライアント側という役割分担です。サーバー側は、ポート番号を指定して待ち受け、接続が来るまで待ちます。クライアント側は、相手のIPアドレスとポート番号を指定して接続しにいき、メッセージを送ります。
「待っている方」と「訪ねていく方」がいる。この形は、このあと最後まで変わりません。
中級のメンバーは、この程度のコードならあっという間に書いてしまいます。そして、驚くほどタイプミスが少ないのです。もっと言えば、エラーコードを読んで自分たちで修正してしまいます。この段階まで来ていれば、通信に進んでも大丈夫だと判断しました。
双方向にする(ここで難易度が上がる)
片道で送れることを確認したら、次はお互いにメッセージをやり取りできるようにします。いわゆるチャットです。
受信を別スレッドにする理由
ここでthreadingが登場します。理由はシンプルで、キーボードからの入力を待っている間は、プログラムがそこで止まってしまうからです。入力を待ちながら、同時に相手からのメッセージも受け取りたい。だから受信の処理を別のスレッドに分けて、裏で動かし続けます。

コードは短いのに、難易度は高い
写経自体は40分ほどで終わりました。ところが、この日は動作確認がうまくいきません。接続まではできたのに、メッセージの往復ができない。結局、この課題は翌月に持ち越しました。
画面で何かが動くコードとは違い、通信は目に見えないやり取りがコードに書かれています。これまで取り組んできたプログラムより、コードは短くても難易度が高い。ここは指導する側も、進め方を工夫する必要があると感じたところです。
ゲームに通信を組み込む
チャットが動いたら、いよいよゲームです。
まず通信なしの基本形を完成させる
先に、通信を使わないシューティングゲームの基本形(game7.py)を完成させます。あえて簡素に作ってあり、必要最低限の機能しか盛り込んでいません。作り込むのは後の工程です。
ここは生成AIに作らせるのではなく、写経です。プログラムとしての形を覚えてもらうことが目的だからです。
サーバー版・クライアント版に書き換える
基本形ができたら、それをサーバー側(gameserver8.py)とクライアント側(gameclient8.py)に書き換えます。通信の仕組み自体は、先に作ったチャットと同じです。待つ側と訪ねる側があって、そこを流れるデータが文字から機体の情報に変わっただけ、と考えると見通しがよくなります。
正直に言えば、この部分の作業は地味です。通信機能があるからゲームが面白くなるのに、通信機能自体のプログラムは面白くないという世の中の仕組みがあります。それでも、飛躍のためには必要な工程です。
なお、「プログラミング=ゲーム作り」という認識があるとしたら、それは誤解です。ゲームは結果が目に見えて楽しいから題材にすることが多い、というだけで、コンピューター同士が通信する部分も、当然プログラミングする必要があります。
2画面が「それぞれの視点」で動く
2台をつないで動かすと、2つの画面で自分と相手の動きが、それぞれの視点で表示されます。冒頭の写真がその場面です。ここではじめて、それまでの地味な作業が何のためだったのかが腑に落ちます。
通信部分とゲーム部分を分ける
動くようになったら、次は改造です。ただしその前に、コードの構造を整理します。

分けると改造できるようになる
ゲームの中身(gamemain9.py)と、通信の担当(gameserver9.py/gameclient9.py)を分けます。こうしておくと、ゲームの見た目やルールをいじるときに通信部分を触らずに済み、逆に通信で不具合が出たときも切り分けがしやすくなります。
改造といっても、まずは現状どういうプログラムなのかという理解が必要です。メンバーには対戦ゲームを実際に動かしながら、いまどこまでできているのかを確認してもらいました。
たとえば、この時点では自機も敵機も横方向にしか動きません。縦にも動かしたらどうなるか。弾の連射がいくらでもできてしまうので、連射制限をかけてみるのはどうか。背景が真っ黒なので、画像を置いてみるのはどうか。こうした改造の入口を用意しておくと、あとは自分たちで広げていきます。
生成AIに任せきりにせず、元のコードを活かす
改造には生成AIを使います。ここで大事にしたのは、AIに自由に作らせるのではなく、元にあるコードを十分に活かしたまま、自分の思う通りに作り替えるという進め方です。AIに任せきりにするのではなく、AIを制御する。地味に見えて、実は高度なことをやっています。

曖昧に問いかければ曖昧な答えが返り、具体的に問いかければ具体的な答えが返ってきます。AIから良い答えを引き出せるかどうかは、こちらの問いかけ次第です。
動かないときに見るところ
ここからが本題かもしれません。通信系のプログラムの大変なところは、プログラムコード以外のところでトラブルが多発するという点です。
コードについては、こちら側で作業範囲を限定して整備しておけば、比較的まともなものが出てきます。しかし、パソコンやネットワークの側に原因があると、まずその切り分けから始めなければなりません。半年間で実際に遭遇したものを挙げておきます。
- 接続先が127.0.0.1のままになっていた。同じパソコンの中でのテスト用の指定です。2台でつなぐときは、相手のIPアドレスに書き換える必要があります
- ゲスト用のSSIDに接続していた。ゲスト用のネットワークは、つながっている端末同士が通信できない設定になっていることがあります。インターネットは見えるのに相手には届かない、という状態になります
- そもそも接続先のSSIDが違っていた。2.4GHzと5GHzで別のSSIDになっている場合もあり、2台が別々のネットワークに乗っているとつながりません
- ファイアウォールの設定。Windowsの「設定」画面から操作してもうまく設定できないことがあり、結局コントロールパネル側から設定しました
- 家庭のパソコンで、子ども向けの利用制限がかかっていて設定を変更できなかった。持ち込みのパソコンを使う場合に起こります
- インターネットにはつながるのに、GitHubにアクセスできない。会場やご家庭の環境によっては、この段階でつまずきます
厄介なのは、まったく問題ないパソコンと、問題だらけのパソコンが混在することです。同じ手順で進めているのに、動く人と動かない人が出る。原因の切り分けは、基本的にスタッフ側で引き受けることになりました。
もし複数人でこのテーマに取り組むなら、当日の前にネットワーク環境の確認をしておくことを強くおすすめします。特に、SSIDがどれか、端末同士の通信が許可されているか、この2点です。
小中学生と取り組んでみてわかったこと
一般的なプログラミングクラブで通信系の内容があまり扱われないのは、こうした事情によるものだと思います。コードを書く以外のところで手が取られるからです。
範囲を限定すれば、小学6年生・中学1年生でもできる
ネットワークの内容を体系的に理解しようとすれば、基本情報技術者試験のレベルが前提になります。それを小中学生に求めるのは現実的ではありません。
ただ、実際にやってみてわかったのは、講師側が扱う範囲を限定して環境を整えておけば、小学6年生・中学1年生でも通信対戦ゲームは完成させられるということです。通信の詳しい仕組みは概要を掴む程度にとどめ、環境まわりの切り分けは大人が引き受ける。この線引きができるかどうかが、うまくいくかどうかの分かれ目だと感じました。
通信プログラムには、必ず相手がいる
この演習は2人1組で進めました。通信のプログラムは、動作確認の時点で必ず相手が必要になるからです。

プログラムは孤独な1人の作業という風に思われるかもしれませんが、違います。接続先の誰かとつながることを意識して、相手のことをおもんぱかりながら進めないといけません。作りたいものを自由に作るのではなく、相手と妥協点を見つけながら創造していく作業が必要になります。
妥協と言いましたが、これは「さらなる高み」と言い換えることができるかもしれません。自分と相手のコンフォートゾーンから外れた外側に、いいアイデアが待っていることがあります。
想定を超えてきた例
最終回で、私の想定を超えてきたメンバーがいました。

プレイヤー1とプレイヤー2は相互に敵同士として戦う、という想定で作っていました。ところが彼らは、生成AIの力を借りながら、それを「2人が協力してコンピューターの敵を倒すゲーム」に改造していたのです。
もちろん、これも通信を使ったゲームです。こういう発想が出てくるのがいいですね。

時間内に完成までたどり着けなかったメンバーもいました。それでも、1人だけではなく誰かと一緒にモノを作るという体験は、1人で作る時とはまた違った楽しさがあるのではないかなと、後ろで見ていて思いました。
半年間の各回の記録
この記事のもとになった、各回の活動報告です。当日の様子や、うまくいかなかったところも含めて書いています。
学校・団体での実施について
光都ICTクラブでは、学校・公民館・自治体・企業向けの出前授業(出張プログラミング・AI講座)も承っています。この記事のような通信を扱う内容は、環境の事前確認が要になりますので、ご相談いただければ会場の状況に合わせて内容を組み立てます。




