Visual Studio での競技プログラミング管理方法

Visual Studio を使った競技プログラミングの始め方について紹介したいと思います.

(追記)競プロなどの手軽な環境としては Visual Studio Code を使用するのがベストだと思います(この記事の存在意義は...).

前置き

以前に書いた記事「Visual Studio で Ubuntu ライクな競プロ環境 - 忘れても大丈夫」では,コンパイラgcc を用いてソリューションやプロジェクトを使用していない Visual Studio もどきの残念な方法を紹介しました.
kusanoさん@がんばらない さんから教えてもらった方法で試してみると最高だったのでここで紹介します.
 
    f:id:tatanaideyo:20210306062033p:plain:w400

注意として私自身が Visual Studio について なんとなく でしか理解していないので正しい説明は他のサイトを参考にしてください.また,他に良い方法などあれば教えて下さると助かります.

目標

ProgrammingContestCpp というソリューションを 1 つ作成して,その下にプログラミングコンテスト毎にプロジェクトを作成します.下の例では AtCoderyukicoder の 2 つのサイトに対応するプロジェクトを作成しています.他に TopCoderCodeforces などを作成しても良いかもしれません.また,1 つのプロジェクトで複数サイトのソースコードを管理しても良いかもしれませんがここでは別々に扱います.
AtCoderCpp プロジェクトでは各コンテスト毎にフォルダを作成してその中で問題毎にソースコードを作成しています.YukicoderCpp プロジェクトの場合はフォルダを作成せずに問題毎にソースコードを作成しています.フォルダを作成するかどうかは好みによると思います.

ソリューションとプロジェクト は,ソリューションが複数のプロジェクトを含むことができ,プロジェクトは 1 つの exe または dll を生成するソースコードやリソースの集まりと理解していれば十分だと思います.C++ では実行可能ファイルで main 関数は 2 つ以上あってはいけません.プロジェクトは 1 つの exe または dll を生成すると言ったので,プロジェクト内に main 関数を含む 2 つ以上のソースコードがあるとコンパイルエラーになります.ただ,競技プログラミングでは出力のほとんどが 1 つの main 関数を含む 1 つのソースコードを提出する形式となっているので,ABC191 フォルダ内の A.cppB.cpp の各ソースコードには main 関数を書きたい気持ちがあります.このもどかしさを上手く扱う方法をこれから説明していきます.

f:id:tatanaideyo:20210306070256p:plain:w300

 

手順

手順1.ソリューション ProgrammingContestCpp を作成

まず初めに ProgrammingContestCpp ソリューションと AtCoderCpp プロジェクトを作成します.ソリューションとプロジェクトの名前は上の画像と同じにしていますが,実際は好きな名前を設定してください.

  1. Visual Studio を開く
  2. 「新しいプロジェクトの作成」を選択
  3. 「空のプロジェクト」を選択して「次へ」をクリック
  4. 「プロジェクト名」に AtCoderCpp と入力
  5. 「ソリューションとプロジェクトを同じディレクトリに配置する」を非選択にする
  6. 「ソリューション名」に ProgrammingContestCpp と入力

上の手順を実行すると下の画像のようになると思います.ここで,右にあるソリューションエクスプローラの「すべてのファイルを表示」を選択します.

f:id:tatanaideyo:20210306071608p:plain:w300
 

手順2.AtCoder Beginner Contest 191 を解く

ABC 191A 問題B 問題 を解いてみます(実際に解かなくてもよいです).
始めに ABC191 フォルダを作成します.

  1. ソリューションエクスプローラAtCoderCpp プロジェクトを右クリック
  2. 「追加」 > 「新しいフォルダー」を選択して ABC191 と入力

次に A 問題 を解きます.

  1. ソリューションエクスプローラABC191 フォルダーを右クリック
  2. 「追加」 > 「新しい項目」を選択
  3. C++ ファイル(.cpp)」を選択して「名前」に A.cpp と入力
  4. 問題 A のソースコードA.cpp として解く
    1. ビルドは AtCoderCpp プロジェクトを右クリックして「ビルド」を選択する
    2. 実行は上のメニューの「デバッグ」 > 「デバッグなしで開始」を選択するか「Ctrl + F5」と入力するとコマンド・プロンプトが立ち上がるのでテストを入力(右クリックするとペーストされる)

f:id:tatanaideyo:20210306075618p:plain:w300

ビルドはコンパイル・リンクをすることと理解すればここでは十分です.ビルドはプロジェクト毎に行えて,上では AtcoderCpp プロジェクトをビルドしました.他にソリューションをビルドすることによってソリューション内に含まれるすべてのプロジェクトをビルドすることができます.ソリューションのビルド方法は,

  • 上のメニューの「ビルド」 > 「ソリューションのビルド」を選択するか「F7」または「Ctrl + Shift + B」を入力
  • ソリューションエクスプローラでソリューション ProgrammingConsoleCpp を右クリック「ソリューションのビルド」を選択

のいずれかを行います(デフォルトショートカットキー).ソリューションをビルドするかプロジェクトのみをビルドするかは時と場合によりますが,他のプロジェクトが変更されていない場合はソリューションをビルドしても良いかもしれません.
また,ビルドをせずに「デバッグなしで開始」を行うと対応するプロジェクトのみ をビルドをしてデバッグなしで実行します.この「対応するプロジェクトのみ」は複数のプロジェクトが存在するときに重要となるので YukicoderCpp プロジェクトを作成したときに説明をします.


次に B 問題 を解きます.ソースコード作成までは上の 3 番目と同じですが,4 番目のビルドをすると A.cppB.cpp の両方に main 関数が存在するので AtCoderCpp のビルドが失敗します. 次では B.cpp ファイルの作成後から説明をします.

  1. ソリューションエクスプローラA.cpp を右クリックして「プロジェクトから除外」を選択する
  2. 問題 B のソースコードB.cpp として解く(4-1 と 4-2 は同じ)

A.cpp をプロジェクトから除外したことによって,プロジェクト内の main 関数は B.cpp の 1 つのみとなり AtCoderCpp のビルドが成功します(バグが無ければ).もし,A.cpp を解きたい場合は次のようにします.

  1. A.cpp を右クリックして「プロジェクトに含める」を選択する
  2. B.cpp を右クリックして「プロジェクトから除外」を選択する.

ソースコードが増えても同様に,コンパイルするソースコードは「プロジェクトに含める」を選択してそれ以外は「プロジェクトから除外」を選択して,プロジェクト内に含まれる main 関数の数が 1 つ以下にしてビルドをします.

f:id:tatanaideyo:20210306075945p:plain:w300

ABC181A 問題 も同様にしてフォルダとファイルを追加して試してみてください.

f:id:tatanaideyo:20210306080941p:plain:w300
 

手順3.yukicoder の問題を解く

yukicoder 用のプロジェクト YukicoderCpp を作成して 問題 9014 を解きます.

  1. ソリューションエクスプローラProgrammingContestCpp ソリューションを右クリック
  2. 「追加」 > 「新しいプロジェクト」 > 「空のプロジェクト」 を選択
  3. 「プロジェクト名」に YukicoderCpp と入力
  4. ソリューションエクスプローラで「すべてのファイルを表示」を選択する(プロジェクト作成後に未選択になっている場合があるので)
  5. YukicoderCpp を右クリックして 「追加」 > 「新しい項目」 > 「C++ファイル(.cpp)」を選択
  6. 「名前」に 9014.cpp と入力


プロジェクトを追加するところ以外のソースコードを追加するところは今までと同じです.ここで実行すると AtCoderCpp プロジェクトが生成した実行可能ファイルが実行されます.

f:id:tatanaideyo:20210306082255p:plain:w300


YukicoderCpp プロジェクトを実行のターゲットにするためには次を行います.
 1. ソリューションエクスプローラYukicoderCpp プロジェクトを右クリック
 2. 「スタートアッププロジェクトに設定」を選択

これで,YukicoderCpp プロジェクトがスタートアップのターゲットとなりました.先ほど

ビルドをせずに「デバッグなしで開始」を行うと対応するプロジェクトのみ をビルドをしてデバッグなしで実行

と書きましたが,ここでの対応するプロジェクトが スタートアッププロジェクト に設定されたプロジェクトを指します.競技プログラミングでの用途は分かりませんがスタートアッププロジェクトで複数のプロジェクトを指定することができます.指定方法は,

  1. ソリューションエクスプローラで ProgrammingContestCpp を右クリック
  2. 「スタートアッププロジェクトの設定」を選択
  3. 「マルチスタートアッププロジェクト」を選択してアクションでスタートアップにするかを選択

です.「デバッグなしで開始」を行うとスタートアップに選択されたプロジェクト毎にコマンド・プロンプトが立ち上がります.

現在,AtCoderCpp では ABC181A.cpp がプロジェクトに含まれており,YukicoderCpp では 9014.cpp がプロジェクトに含まれていますが,異なるプロジェクトなのでビルドすることができます.

蛇足ではありますが YukicoderCpp問題 9013 も作成して解いてみてください.

f:id:tatanaideyo:20210306083318p:plain:w300


 

まとめ

ソリューションには複数のプロジェクトを含めることができ,それぞれのプロジェクト毎に 1 つの実行可能ファイルが生成されます.ただし,プロジェクト内で main 関数を含むことができるソースコードは 1 つ以下なので,対象となるソースコード以外はプロジェクトから除外してビルドをします.プロジェクトの実行はソリューションのプロパティのスタートアッププロジェクトに設定されているプロジェクトが実行されます.
プロジェクト,フォルダやソースコードを削除するときはソリューションエクスプローラで対象のものを右クリックして「削除」を選択してください.

以上で Visual Studio 上で競技プログラミングを始める準備ができたと思います.Visual Studio は IntelliSense やデバッガなど便利な機能があるので競技プログラミングで使うエディタ(統合開発環境)として選択肢に入れても良いと思います.