一攫千金プログラミングpaizajackにPerlのサンプルコードが存在しない問題

# 始めに

[paiza](https://paiza.jp/)というエンジニア向けの転職サービスやプログラミング学習サービスなどを提供されているところから、[一攫千金プログラミング〜ボットdeジャックポット paizajack](https://paiza.jp/paizajack/)（以下paizajack）と呼ばれるサービスが先日開始されたそうです。

...という話を先ほど見つけました。
簡単なゲームシステムの説明などは、こちらの参考ページを参照してください。

　参考ページ : [一攫千金プログラミングpaizajackを遊んでみた](https://qiita.com/kithz39/items/5550246c40ac5cab170c)

そして、僕も面白そうだと思って~~（一攫千金という言葉につられて）~~始めてみようと思いました。

追記：
サンプルコードのGitHubリポジトリを作りました。
[paizajack by Perl](https://github.com/Morichan/paizajack_by_Perl)



# paizaの簡単な~~（多分間違った）~~紹介

簡単に、paiza[^whats_paiza]のシステムについて説明します。

paizaを一言で表すならば、ウェブブラウザでプログラミングが実行できる環境を提供しているサイト、です[^sorry]。
そのコンテンツとして、様々なゲームが存在しており、paizajackもその1つです。
実行環境は、恐らくpaiza.ioに似た（あるいは同じ）環境が入っていると思われます（正確な答えは不明です）。
~~時々エラーで止まったりします[^paiza_environment]。~~

[^whats_paiza]: 実は、paizaには複数のコンテンツがあります。名前がややこしく（これらは間違っている可能性もありますが）、[paiza](https://paiza.jp/guide/career)や[paiza新卒](https://paiza.jp/guide/student)や[EN:TRY](https://paiza.jp/guide/en_try)と呼ばれる転職支援サービス、[paizaラーニング](https://paiza.jp/guide/works)と呼ばれるプログラミング入門学習コンテンツ、[POH (Paiza Online Hackathon)](https://paiza.jp/paiza_game_history)と呼ばれるゲームコンテンツ、[paiza.io](https://paiza.io/ja)と呼ばれるオンライン実行環境サービスがあるみたいです。本記事では簡略化のために、POHおよびpaiza.ioのことをpaizaと呼びます。

[^sorry]: 本記事ではそういうことにしておいてください。怒られる覚悟です。

[^paiza_environment]: [paizaのサイトに提出されるコードのテスト環境](https://paiza.jp/guide/language)は、Perlの場合はバージョン 5.22.1、メモリ制限は512MBです。



# サンプルコードが存在しない問題

このゲームに限らず、paizaのゲームでは様々なプログラミング言語[^paiza_language]を用いることができます。
しかし、ウェブ経由での開発という環境のため、入出力に特殊な技術を使っているようです。
そのため、最初のサンプルコードの有無によって、その後の開発に大きな差が出ます。

[^paiza_language]: paizaでは、サービス開始初期から対応していた言語
 (Java, PHP, Ruby, Python2, Python3, Perl, C, C++, C#, JavaScript) およびBeta版対応言語（一部は正式対応に昇格）があります。

さて、端的に言います。

**Perlのサンプルコードは存在しません。**

サンプルコードが存在する言語はJava, PHP, Ruby, Python2, Python3, C, C++, C#, JavaScriptだけ[^paiza_language_without_perl]です。

[^paiza_language_without_perl]: なぜサービス開始初期から対応していた言語のうち、Perlだけ無いのでしょうか？



# サンプルコードが無ければ作ればいいじゃない

ということで、サンプルコードを作りました。
下記のコードをコピペすれば、サンプルコードとして機能します。

``` perl:sample_code.pl
use List::Util qw/sum/;

chomp(my $line_1 = <STDIN>);
my @my_card = split(" ", $line_1);

if ($my_card[0] eq 0) {
    print "1"; # 賭けチップ数

} else {
    if (sum(@my_card) < 10) { # ★カードを引く条件の合計値を変えてみよう！★
        print "HIT"; # カード引く
    } else {
        print "STAND"; # 勝負する
    }
}
```

元のコードはPHPのサンプルコードです。
変数名やコメント内容などはできる限りそのままにしています。

本記事の内容は以上です。



# おまけ もう少しまとも？なサンプルコード

あまり必要ないとは思いますが、僕が考えた最強のサンプルコードを載せておきます。
これでみなさんも、Perlでpaizajackしてみましょう！

ついでに、PODにも挑戦してみました（実はこれがやってみたかっただけ）。
無駄に長くなっています。
サンプルコードの意味とは...？

paizajackの仕様上、1つのファイルしか読み込めないという制約により、`main`パッケージと`Card`パッケージを同じファイル内に入れています。
このコードも、コピペすれば使えます。

``` perl:paizajack_sample.pl
use strict;
use warnings;

main();

sub main {
    my $card = Card->new;

    $card->stdin_card;

    $card->start_game;
}



package Card;

use strict;
use warnings;

=encoding utf8

=head1 NAME

Card - paizajack用サンプルモジュールです。

=head1 VERSION

Version 0.01

=cut

our $VERSION = '0.01';


=head1 SYNOPSIS

簡単な使い方

    use Card;

    my $card = Card->new;

    $card->stdin_card;

    $card->start_game;


=head1 EXPORT

このモジュールは、L<paizajack|https://paiza.jp/paizajack/>での
使用を想定したサンプルモジュールです。
適当に作りましたので、適当に書き換えてください。
シンプルな作りを目指しました。

=head1 SUBROUTINES/METHODS

=head2 new

みんな大好きnewメソッドです。
インスタンス生成時にお使いください。

メンバ変数として保持しているものを、次に示します。

=over 4

=item *
カードの数値情報の配列

=item *
賭けチップ数

=back

=cut

sub new {
    my $class = shift;
    my $self = {
        card => [],
        betted_chips => 1,
    };
    return bless $self, $class;
}

=head2 stdin_card

カード情報を標準入力から取得するメソッドです。

=cut

sub stdin_card {
    my $self = shift;

    chomp( my $line = <STDIN> );
    my @card = split " ", $line;

    $self->{card} = \@card;
}

=head2 start_game

ゲームを開始します。

ゲーム開始と言いつつ、ゲーム開始の前処理をしています。
ゲーム開始前である場合は、賭けチップ数を提示します。

ゲーム中は、保持しているカードの合計値が閾値を超えるまで、
カードを引き続けます。
閾値を超えた場合は、カードを引くのを止めます。

=cut

sub start_game {
    my $self = shift;

    if( $self->is_first_dealing ) {
        $self->print_betted_chips;

    } else {
        if( $self->is_continuing_game ) {
            $self->print_draw_card;
        } else {
            $self->print_stand;
        }
    }
}

sub is_first_dealing {
    my $self = shift;
    my $is_first = 0;

    $is_first = 1 if $self->{card}->[0] == 0;

    return $is_first;
}

sub is_continuing_game {
    my $self = shift;
    my $is_continuing = 0;

    $is_continuing = 1 if $self->sum < 10; # 閾値

    return $is_continuing;
}

sub sum {
    my $self = shift;
    my $sum_card_number = 0;

    foreach ( @{ $self->{card} } ) {
        $sum_card_number += $_;
    }

    return $sum_card_number;
}

sub print_betted_chips {
    my $self = shift;
    print $self->{betted_chips}; # 賭けチップ数
}

sub print_draw_card {
    my $self = shift;
    print "HIT"; # カードを引く
}

sub print_stand {
    my $self = shift;
    print "STAND"; # 勝負する
    $self->{is_stopped_game} = 1;
    $self->{is_gaming} = 0;
}

=head1 AUTHOR

Morichan

=head1 COPYRIGHT & LICENSE

Copyright (c) 2017 Morichan

This software is released under the MIT License.
https://opensource.org/licenses/mit-license.php

=cut

1;
```

ここまで読んでくださって、ありがとうございます。
もしおかしい点、気づいた点などございましたら、教えていただけると幸いです。
特にPODは初めて書いたので、いろいろおかしいかもしれません。
また、paizaについても適当に調べただけなので、おかしい箇所があると思います。