Created
May 21, 2012 04:51
-
-
Save makamaka/2760603 to your computer and use it in GitHub Desktop.
やったー Yaircで○×ゲームできたよー
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Yairc::Plugin::OXGame; | |
=pod | |
○×ゲーム | |
3×3のマスに○と×を交互に置いて | |
タテ・ヨコ・ナナメ3連続になった方の勝ち | |
タグは #ox | |
まずはTAGSにoxを追加しておきましょう。 | |
本文に join が含まれると参加 | |
二人揃うとゲーム開始(一人で2回joinしてもok) | |
a b c | |
┌─┬─┬─┐ | |
1 │ │ │ │ | |
├─┼─┼─┤ | |
2 │ │ │ │ | |
├─┼─┼─┤ | |
3 │ │ │ │ | |
└─┴─┴─┘ | |
a1 あるいは 1a と打てば左上隅に○(もしくは×)が置かれる | |
他のマスも同様。 | |
view と打つと本人にのみ現在の盤面が表示される | |
help でコマンドリスト | |
quit でゲーム離脱 | |
ex. | |
join #ox | |
view #ox | |
Let's enjoy! | |
=cut | |
use strict; | |
use warnings; | |
use utf8; | |
my $USER = {}; | |
my $BOARD = [[0,0,0],[0,0,0],[0,0,0]]; | |
my @TURN; # idx 0 is the user in turn. | |
my $TURN; # count | |
sub setup { | |
my ( $class, $sys ) = @_; | |
$sys->register_calling_tag( 'OX', sub { | |
my ( $sys, $socket, undef, $message_ref, $tags ) = @_; | |
my $user; | |
$socket->get('user_data', sub { | |
$user = $_[2]; | |
}); | |
return unless $user; | |
my $text = ''; | |
my $game_is_over; | |
my $entried; | |
if ( $$message_ref =~ /join/ ) { | |
my $num = @TURN; | |
if ( $num == 2 ) { | |
$text .= "定員に達しています。\n"; | |
} | |
else { | |
if ( $num == 1 and $TURN[0]->[0] == 2 ) { | |
$num = 0; | |
} | |
$USER->{ $user->{ token } } = [ $num + 1, $user ]; | |
push @TURN, [ $num + 1, $user ]; | |
$text .= $user->{ nickname } . "が参加しました。\n"; | |
$text .= "(※ゲームセット時のみログに残ります)\n"; | |
$entried = 1; | |
} | |
} | |
elsif ( $$message_ref =~ /help/ ) { | |
$text .= "join ... 参加\n"; | |
$text .= "quit ... 離脱\n"; | |
$text .= "view ... 閲覧\n"; | |
} | |
elsif ( $$message_ref =~ /view/ ) { | |
$text .= board(); | |
$socket->emit( 'user message', make_post( $sys, $text ) ); | |
return; | |
} | |
elsif ( $$message_ref =~ /quit/ ) { | |
quit_player( $user ); | |
} | |
elsif ( scalar( @TURN ) == 2 && exists $USER->{ $user->{ token } } ) { | |
my $turn = $USER->{ $user->{ token } }; | |
if ( scalar( keys %$USER ) == 1 ) { # 一人プレイの場合 | |
$turn = $TURN[0]; | |
} | |
if ( $TURN[0]->[0] == $turn->[0] ) { | |
my ( $row ) = $$message_ref =~ /([123])/; | |
my ( $col ) = $$message_ref =~ /([abc])/; | |
$col = $col eq 'a' ? 1 | |
: $col eq 'b' ? 2 | |
: $col eq 'c' ? 3 | |
: 0; | |
if ( $col and $row ) { | |
if ( $BOARD->[ $row - 1 ]->[ $col - 1 ] ) { | |
$text .= "そこは既に置かれています。\n"; | |
} | |
else { | |
$TURN++; | |
$BOARD->[ $row - 1 ]->[ $col - 1 ] = $turn->[0]; | |
if ( $game_is_over = is_game_over( $row - 1, $col - 1 ) ) { | |
$text .= "ゲームセット! " . $TURN[0]->[1]->{ nickname } . "の勝ち\n"; | |
} | |
elsif ( $TURN == 9 ) { | |
$text = "ゲームセット! 引き分け\n" . $text; | |
$game_is_over = 1; | |
} | |
@TURN = @TURN[1,0]; | |
} | |
} | |
} | |
else { | |
return; | |
} | |
} | |
else { | |
return; | |
} | |
$text .= board(); | |
if ( $game_is_over ) { | |
%$USER = (); | |
@TURN = (); | |
$BOARD = [[0,0,0],[0,0,0],[0,0,0]]; | |
$TURN = 0; | |
$sys->data_storage->add_post( make_post( $sys, $text ) ); | |
} | |
$sys->send_post_to_tag_joined( make_post( $sys, $text ), 'OX' ); | |
} ); | |
$sys->register_hook( 'disconnected', sub { | |
my ( $sys, $socket ) = @_; | |
my $user; | |
$socket->get('user_data', sub { | |
$user = $_[2]; | |
}); | |
} ); | |
} | |
sub quit_player { | |
my ( $user ) = @_; | |
return unless $user->{ token }; | |
delete $USER->{ $user->{ token } }; | |
@TURN = grep { $_->[1]->{ token } ne $user->{ token } } @TURN; | |
} | |
sub is_game_over { | |
my ( $row_num, $col_num ) = @_; | |
# yoko | |
my $d = $BOARD->[ $row_num ]; | |
if ( $d->[0] == $d->[1] and $d->[0] == $d->[2] ) { | |
return 1; | |
} | |
# tate | |
if ( | |
$BOARD->[ 0 ]->[ $col_num ] == $BOARD->[ 1 ]->[ $col_num ] | |
and $BOARD->[ 0 ]->[ $col_num ] == $BOARD->[ 2 ]->[ $col_num ] | |
) | |
{ | |
return 1; | |
} | |
# naname | |
if ( ($row_num == 0 and $col_num == 0) or ($row_num == 1 and $col_num == 1) | |
or ($row_num == 2 and $col_num == 2) ) | |
{ | |
return 1 if ( $BOARD->[ 0 ]->[ 0 ] == $BOARD->[ 1 ]->[ 1 ] | |
and $BOARD->[ 0 ]->[ 0 ] == $BOARD->[ 2 ]->[ 2 ] ); | |
} | |
if ( ($row_num == 0 and $col_num == 2) or ($row_num == 1 and $col_num == 1) | |
or ($row_num == 2 and $col_num == 0) ) | |
{ | |
return 1 if ( $BOARD->[ 0 ]->[ 2 ] == $BOARD->[ 1 ]->[ 1 ] | |
and $BOARD->[ 0 ]->[ 2 ] == $BOARD->[ 2 ]->[ 0 ] ); | |
} | |
return 0; | |
} | |
sub board { | |
my $text = ''; | |
for ( @TURN ) { | |
my ( $num, $user ) = @{$_}; | |
$text .= $num == 1 ? '○' : '×'; | |
$text .= ":" . $user->{ nickname } . "\n"; | |
} | |
$text .= " a b c\n ┌─┬─┬─┐\n"; | |
my $i = 1; | |
for my $row ( @{ $BOARD } ) { | |
$text .= "$i │"; | |
for my $col ( @$row ) { | |
if ( $col == 0 ) { | |
$text .= ' '; | |
} | |
elsif ( $col == 1 ) { | |
$text .= '○'; | |
} | |
elsif ( $col == 2 ) { | |
$text .= '×'; | |
} | |
$text .= '│'; | |
} | |
$text .= "\n"; | |
$text .= " ├─┼─┼─┤\n" if $i++ < 3; | |
} | |
$text .= " └─┴─┴─┘\n"; | |
return $text; | |
} | |
sub make_post { | |
my ( $sys, $message ) = @_; | |
return { | |
id => '-1', | |
text => $message, | |
nickname => '○×ゲーム', | |
user_key => '+:ox', | |
tags => ['OX'], | |
created_at_ms => $sys->data_storage->_get_now_micro_sec, | |
is_message_log => JSON::false, | |
profile_image_url => '', | |
}; | |
} | |
1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment