diff --git a/src/api/stream/othello-game.ts b/src/api/stream/othello-game.ts
index 9ca4864a54..cc936805ba 100644
--- a/src/api/stream/othello-game.ts
+++ b/src/api/stream/othello-game.ts
@@ -3,6 +3,7 @@ import * as redis from 'redis';
 import Game, { pack } from '../models/othello-game';
 import { publishOthelloGameStream } from '../event';
 import Othello from '../../common/othello/core';
+import * as maps from '../../common/othello/maps';
 
 export default function(request: websocket.request, connection: websocket.connection, subscriber: redis.RedisClient, user: any): void {
 	const gameId = request.resourceURL.query.game;
@@ -105,16 +106,25 @@ export default function(request: websocket.request, connection: websocket.connec
 					bw = freshGame.settings.bw as number;
 				}
 
+				function getRandomMap() {
+					const mapCount = Object.entries(maps).length;
+					const rnd = Math.floor(Math.random() * mapCount);
+					return Object.entries(maps).find((x, i) => i == rnd)[1].data;
+				}
+
+				const map = freshGame.settings.map != null ? freshGame.settings.map : getRandomMap();
+
 				await Game.update({ _id: gameId }, {
 					$set: {
 						started_at: new Date(),
 						is_started: true,
-						black: bw
+						black: bw,
+						'settings.map': map
 					}
 				});
 
 				//#region 盤面に最初から石がないなどして始まった瞬間に勝敗が決定する場合があるのでその処理
-				const o = new Othello(freshGame.settings.map, {
+				const o = new Othello(map, {
 					isLlotheo: freshGame.settings.is_llotheo
 				});
 
diff --git a/src/web/app/common/views/components/othello.room.vue b/src/web/app/common/views/components/othello.room.vue
index 6c8ce16531..745074b17a 100644
--- a/src/web/app/common/views/components/othello.room.vue
+++ b/src/web/app/common/views/components/othello.room.vue
@@ -5,6 +5,7 @@
 	<p>ゲームの設定</p>
 
 	<el-select class="map" v-model="mapName" placeholder="マップを選択" @change="onMapChange">
+		<el-option label="ランダム" :value="null"/>
 		<el-option-group v-for="c in mapCategories" :key="c" :label="c">
 			<el-option v-for="m in maps" v-if="m.category == c" :key="m.name" :label="m.name" :value="m.name">
 				<span style="float: left">{{ m.name }}</span>
@@ -13,7 +14,7 @@
 		</el-option-group>
 	</el-select>
 
-	<div class="board" :style="{ 'grid-template-rows': `repeat(${ game.settings.map.length }, 1fr)`, 'grid-template-columns': `repeat(${ game.settings.map[0].length }, 1fr)` }">
+	<div class="board" v-if="game.settings.map != null" :style="{ 'grid-template-rows': `repeat(${ game.settings.map.length }, 1fr)`, 'grid-template-columns': `repeat(${ game.settings.map[0].length }, 1fr)` }">
 		<div v-for="(x, i) in game.settings.map.join('')"
 			:class="{ none: x == ' ' }"
 			@click="onPixelClick(i, x)"
@@ -124,12 +125,20 @@ export default Vue.extend({
 
 		onUpdateSettings(settings) {
 			this.game.settings = settings;
-			const foundMap = Object.entries(maps).find(x => x[1].data.join('') == this.game.settings.map.join(''));
-			this.mapName = foundMap ? foundMap[1].name : '-Custom-';
+			if (this.game.settings.map == null) {
+				this.mapName = null;
+			} else {
+				const foundMap = Object.entries(maps).find(x => x[1].data.join('') == this.game.settings.map.join(''));
+				this.mapName = foundMap ? foundMap[1].name : '-Custom-';
+			}
 		},
 
 		onMapChange(v) {
-			this.game.settings.map = Object.entries(maps).find(x => x[1].name == v)[1].data;
+			if (v == null) {
+				this.game.settings.map = null;
+			} else {
+				this.game.settings.map = Object.entries(maps).find(x => x[1].name == v)[1].data;
+			}
 			this.$forceUpdate();
 			this.updateSettings();
 		},