ひたすらアウトプット

自分でアウトプットするため用のブログです。月1くらいでなんかアウトプットできればと思ってます。

Visual Studio 2019/2017で競技プログラミング用に環境構築(AtCoder/C++)

1.概要

競技プログラミングする際、よく普段私はVisualStudio2019でコード書くので、一度VS2019/2017で環境構築で環境構築してみようと思いました。

メリットとしては、

VS2019や2017で気軽に競技プログラミングしたい方におすすめです。

バッチファイル作ったりCmakeListsを作る必要があるので、めんどくさい方は以下に上げておいたのでよかったら参考にしてください。

github.com

2.実行環境

Windows 10 Home 64bit 20H2

Cmake 3.18.0

Python 3.9.2

3-1.必要なアプリケーションのインストール

自動でプロジェクト作ったり、自動でサンプルコードを持ってくるためにいくつか必要なアプリケーションがあります。

Cmakeのインストール

VisualStudio用のソリューション等を問題ごとに自動で生成するために使用します。

以下から対象のインストーラを探してインストールを行ってください。

cmake.org

WindowsコマンドプロンプトでCmakeのパスが通ってればOKです。

Pythonのインストール

Pythononline-judge-toolsと呼ばれる競技プログラミングにおいて便利なツールがあるのでそれを使用して、サンプルコードの取得、サンプルのテストを行うために使用します。

以下のようにインストールを行ってください。

www.python.jp

ただリンク先のダウンロードが非公式のサイトからダウンロードしてるんで公式からインストーラは持ってきてもいいかも、

www.python.org

WindowsコマンドプロンプトPythonのパスが通ってれば大丈夫です。

pipからonline-judge-toolsを取得

コマンドプロンプトにて、

C:\Users\user1>python -m pip install online-judge-tools

と入力します。

コマンドプロンプトにてojと入力してパスが通ってればOKです。

3-2バッチファイルの作成

サンプルのダウンロード

バッチファイルを作成して、自動で問題毎にソリューションを作成します。

abc128_a問題を持ってくるとすると、ユーザーにabc128_aをまずバッチファイル上で入力してもらい、ojでサンプルを取得してきます。 以下がサンプルコードになります。

@ECHO OFF
:: 文字コードをutf-8に
chcp 65001
:: 問題を入力
:INPUT_START
ECHO +-------------------------------------------------------+
ECHO  問題を入力してください(例:abc012_a)
ECHO +-------------------------------------------------------+
SET INPUT_STR=
SET /P INPUT_STR=
 
IF "%INPUT_STR%"=="" GOTO :INPUT_START
 
ECHO +-------------------------------------------------------+
ECHO  [%INPUT_STR%]のサンプルを取得します。
ECHO +-------------------------------------------------------+

:: online-judge-toolsからサンプルをDL

oj dl https://"%INPUT_STR:~0,6%".contest.atcoder.jp/tasks/"%INPUT_STR%"

oj dlすると、abc128_a.in及びabc128_a.outが出力されます。

フォルダ構成からダウンロードしたファイル及びCPPファイルを作成

また、Cmakeを用いて、VS用のプロジェクトを作成していきます。フォルダ構成によって結構変わってくるとは思います。 私のフォルダ構成は、

.
├templete.cpp //問題のcppファイルを生成するための
├─Build // VS用のプロジェクトのフォルダ
│  ├─abcXXX_c
│  ├─abcXXX_d
│  ├─abcXXX_a
├─Include //bitsなどのインクルードをするためのフォルダ
│  └─bits
├─Source //それぞれの問題のソースコード用フォルダ
└─test //それぞれの問題のサンプルケースを格納するフォルダ
    ├─128_d
    ├─abcXXX_c
    ├─abcXXX_d
    ├─abcXXX_a
    ├─abcXXX_b
    └─abcXXX_c

Source内にテンプレートのcppファイルから問題のコードを作成し、それぞれのフォルダに格納していくバッチファイルを作成します。

Cmakeを用いてプロジェクト生成

最後にCmakeを用いてプロジェクトを生成します。 まずバッチファイルにて事前にビルド構成やディレクトリを設定します。

:: カレントパスをSOURCE_DIRにセット
set SOURCE_DIR=%~dp0

:: buildディレクトリをSOURCE_DIRにセット
set BUILD_DIR=%SOURCE_DIR%\Build\"%INPUT_STR%"

:: ビルド構成(コンパイラー、アーキテクチャ)を指定
set GENERATOR_NAME=Visual Studio 16

CmakeKListsを作成します。私は以下のような感じで作成しました。

cmake_minimum_required(VERSION 3.1)
project($ENV{INPUT_STR} CXX)
# XXX.in XXX.outファイルをすべてプロジェクトに追加して閲覧できるように
file( GLOB INPUT_SOURCES ./test/$ENV{INPUT_STR}/*.in )
file( GLOB OUTPUT_SOURCES ./test/$ENV{INPUT_STR}/*.out )
# 必要なファイルをプロジェクトに追加
add_executable($ENV{INPUT_STR} ./Source/$ENV{INPUT_STR}.cpp
                                ${INPUT_SOURCES}
                                ${OUTPUT_SOURCES}
                                ./test/$ENV{INPUT_STR}/input.txt
                                ./test/$ENV{INPUT_STR}/output.txt)
# #include <bits/stdc++.h>等を呼べるように
target_include_directories($ENV{INPUT_STR} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Include/)
# リンカーの設定をコンソールに
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE")
# input.txtから値を持ってきて実行し、output.txtへ出力結果を出力する
set_target_properties($ENV{INPUT_STR} PROPERTIES VS_DEBUGGER_COMMAND_ARGUMENTS "<$ENV{HOME_DIR}\\test\\$ENV{INPUT_STR}\\input.txt> $ENV{HOME_DIR}\\test\\$ENV{INPUT_STR}\\output.txt")
                               
set_target_properties($ENV{INPUT_STR} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/Source/")
set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT "$ENV{INPUT_STR}")

4.結論

思っていたよりCmakeやバッチファイル関連はあんまり触ってないとめんどくさいかもです。私はバッチファイルあんまり書いてこなかったので時間かかりました。大体調べれば出てくるとは思います。