From 6299cb8641a48afce95cb577ae011554046f9f56 Mon Sep 17 00:00:00 2001 From: Kouji Takao Date: Mon, 26 Aug 2024 15:30:37 +0900 Subject: [PATCH 1/2] feat: add some method --- src/containers/ruby-tab/koshien-snippets.json | 92 ++++++++++++------- src/lib/ruby-generator/koshien.js | 23 ++++- src/lib/ruby-to-blocks-converter/koshien.js | 53 ++++++++++- .../ruby-tab/extension_koshien.test.js | 45 ++++++++- 4 files changed, 175 insertions(+), 38 deletions(-) diff --git a/src/containers/ruby-tab/koshien-snippets.json b/src/containers/ruby-tab/koshien-snippets.json index fd9dbc5617c..3483f5b2749 100644 --- a/src/containers/ruby-tab/koshien-snippets.json +++ b/src/containers/ruby-tab/koshien-snippets.json @@ -4,79 +4,107 @@ "description": "プレイヤー名を (player1) にして、ゲームサーバへ接続する" }, "koshien.move_to": { - "snippet": "koshien.move_to(${1:0}, ${2:0})", - "description": "x座標 (0)、y座標 (0) に移動する" + "snippet": "koshien.move_to(${1:\"0:0\"})", + "description": "座標 (0:0) に移動する" }, "koshien.get_map_area": { - "snippet": "koshien.get_map_area(${1:0}, ${2:0})", - "description": "x座標が (0) 、y座標が (0) 付近のマップ情報を取得する" + "snippet": "koshien.get_map_area(${1:\"0:0\"})", + "description": "座標 (0:0) 付近のマップ情報を取得する" }, "koshien.map": { - "snippet": "koshien.map(${1:0}, ${2:0})", - "description": "x座標が (0) 、y座標が (0) のマップ情報" + "snippet": "koshien.map(${1:\"0:0\"})", + "description": "座標 (0:0) のマップ情報" + }, + "koshien.calc_goal_route": { + "snippet": "koshien.calc_route(result: list(${4:\"$最短経路\"}))", + "description": "ゴールまでの最短経路をリスト [最短経路] に保存する" }, "koshien.calc_route": { - "snippet": "koshien.calc_route(src: [${1:0}, ${2:0}], dst: [${3:0}, ${4:0}], except_cells: ${5:\"通らない座標\"}, result: ${6:\"最短経路\"})", - "description": "2点間の最短経路 始点 x座標 (0) y座標 (0) 終点 x座標 (0) y座標 (0) 通らない座標 リスト (通らない座標) をリスト (最短経路) に保存する" + "snippet": "koshien.calc_route(result: list(${1:\"$最短経路\"}), src: ${2:\"0:0\"}, dst: ${3:\"0:0\"}, except_cells: list(${4:\"$通らない座標\"}))", + "description": "最短経路 (始点 座標 (0:0) 終点 座標 (0:0) 通らない座標 リスト [通らない座標]) をリスト [最短経路] に保存する" }, "koshien.set_dynamite": { - "snippet": "koshien.set_dynamite([${1:0},${2:0}])", - "description": "ダイナマイトをx座標 (0) y座標 (0) に置く" + "snippet": "koshien.set_dynamite(${1:\"0:0\"})", + "description": "ダイナマイトを座標 (0:0) に置く" }, "koshien.set_bomb": { - "snippet": "koshien.set_bomb([${1:0},${2:0}])", - "description": "爆弾をx座標 (0) y座標 (0) に置く" + "snippet": "koshien.set_bomb(${1:\"0:0\"})", + "description": "爆弾を座標 (0:0) に置く" + }, + "koshien.map_all": { + "snippet": "$すべてのマップ情報 = koshien.map_all", + "description": "すべてのマップ情報" }, - "koshien.save_map_all": { - "snippet": "koshien.save_map_all(${1:\"map1\"})", - "description": "すべてのマップ情報を (map1) に保存する" + "koshien.map_from": { + "snippet": "$マップ情報 = koshien.map_from(${1:\"0:0\"}, ${2:$すべてのマップ情報})", + "description": "座標 (0:0) のマップ情報を [すべてのマップ情報] から読み込む" }, - "koshien.load_map": { - "snippet": "koshien.load_map(${1:\"map1\"}, ${2:0}, ${3:0})", - "description": "x座標が (0) 、y座標が (0) のマップ情報を (map1) から読み込む" + "koshien.locate_objects": { + "snippet": "koshien.locate_objects(result: list(${1:\"$地形・アイテムの座標\"}), cent: ${2:\"0:0\"}, sq_size: ${3:5}, objects: ${4:\"ABCD\"})", + "description": "範囲内の地形・アイテム (中心 座標 (0:0) 、範囲 (5) 、地形・アイテム (ABCD) )をリスト [地形・アイテムの座標] に保存する" + }, + "koshien.other_player": { + "snippet": "koshien.other_player", + "description": "[対戦キャラクタ] の [座標]" }, "koshien.other_player_x": { "snippet": "koshien.other_player_x", - "description": "対戦キャラクタの x座標" + "description": "[対戦キャラクタ] の [x座標]" }, "koshien.other_player_y": { "snippet": "koshien.other_player_y", - "description": "対戦キャラクタの y座標" + "description": "[対戦キャラクタ] の [y座標]" + }, + "koshien.player": { + "snippet": "koshien.player", + "description": "[プレイヤー] の [座標]" }, "koshien.player_x": { "snippet": "koshien.player_x", - "description": "プレイヤーの x座標" + "description": "[プレイヤー] の [x座標]" }, "koshien.player_y": { "snippet": "koshien.player_y", - "description": "プレイヤーの y座標" + "description": "[プレイヤー] の [y座標]" + }, + "koshien.enemy": { + "snippet": "koshien.enemy", + "description": "[妨害キャラクター] の [座標]" }, "koshien.enemy_x": { "snippet": "koshien.enemy_x", - "description": "妨害キャラクタの x座標" + "description": "[妨害キャラクター] の [x座標]" }, "koshien.enemy_y": { "snippet": "koshien.enemy_y", - "description": "妨害キャラクタの y座標" + "description": "[妨害キャラクター] の [y座標]" + }, + "koshien.goal": { + "snippet": "koshien.goal", + "description": "[ゴール] の [x座標]" }, "koshien.goal_x": { "snippet": "koshien.goal_x", - "description": "ゴールの x座標" + "description": "[ゴール] の [x座標]" }, "koshien.goal_y": { "snippet": "koshien.goal_y", - "description": "ゴールの y座標" + "description": "[ゴール] の [y座標]" }, "koshien.turn_over": { "snippet": "koshien.turn_over", "description": "ターンを終了する" }, - "koshien.coordinate_of_x": { - "snippet": "koshien.coordinate_of_x(${1:'0:0'})", - "description": "(0:0) のx座標" + "koshien.position_of_x": { + "snippet": "koshien.position_of_x(${1:\"0:0\"})", + "description": "(0:0) の [x座標]" + }, + "koshien.position_of_y": { + "snippet": "koshien.position_of_y(${1:\"0:0\"})", + "description": "(0:0) の [y座標]" }, - "koshien.coordinate_of_y": { - "snippet": "koshien.coordinate_of_y(${1:'0:0'})", - "description": "(0:0) のy座標" + "koshien.object": { + "snippet": "koshien.object(${1:\"unknown\"})", + "description": "[未探索のマス]" } } diff --git a/src/lib/ruby-generator/koshien.js b/src/lib/ruby-generator/koshien.js index 7486a3d3848..dfab339d458 100644 --- a/src/lib/ruby-generator/koshien.js +++ b/src/lib/ruby-generator/koshien.js @@ -24,6 +24,15 @@ export default function (Generator) { return `koshien.move_to(${position})\n`; }; + Generator.koshien_calcGoalRoute = function (block) { + const resultListName = Generator.listNameByName( + Generator.getFieldValue(block, 'RESULT', Generator.ORDER_NONE) + ); + const result = resultListName ? `list(${Generator.quote_(resultListName)})` : 'nil'; + + return `koshien.calc_route(result: ${result})\n`; + }; + Generator.koshien_calcRoute = function (block) { const src = Generator.valueToCode(block, 'SRC', Generator.ORDER_NONE) || Generator.quote_('0:0'); const dst = Generator.valueToCode(block, 'DST', Generator.ORDER_NONE) || Generator.quote_('0:0'); @@ -61,7 +70,7 @@ export default function (Generator) { Generator.koshien_locateObjects = function (block) { const position = Generator.valueToCode(block, 'POSITION', Generator.ORDER_NONE) || Generator.quote_('0:0'); const sqSize = Generator.valueToCode(block, 'SQ_SIZE', Generator.ORDER_NONE) || 5; - const objects = Generator.valueToCode(block, 'OBJECTS', Generator.ORDER_NONE) || Generator.quote_('A B C D'); + const objects = Generator.valueToCode(block, 'OBJECTS', Generator.ORDER_NONE) || Generator.quote_('ABCD'); const resultListName = Generator.listNameByName( Generator.getFieldValue(block, 'RESULT', Generator.ORDER_NONE) ); @@ -73,7 +82,10 @@ export default function (Generator) { Generator.koshien_targetCoordinate = function (block) { const target = Generator.getFieldValue(block, 'TARGET') || 'player'; - const coordinate = Generator.getFieldValue(block, 'COORDINATE') || 'x'; + const coordinate = Generator.getFieldValue(block, 'COORDINATE') || 'position'; + if (coordinate === 'position') { + return [`koshien.${target}`]; + } return [`koshien.${target}_${coordinate}`]; }; @@ -89,9 +101,14 @@ export default function (Generator) { Generator.koshien_positionOf = function (block) { const position = Generator.valueToCode(block, 'POSITION', Generator.ORDER_NONE) || Generator.quote_('0:0'); - const coordinate = Generator.getFieldValue(block, 'COORDINATE') || null; + const coordinate = Generator.getFieldValue(block, 'COORDINATE') || 'x'; return [`koshien.position_of_${coordinate}(${position})`]; }; + Generator.koshien_object = function (block) { + const object = Generator.quote_(Generator.getFieldValue(block, 'OBJECT') || 'unknown'); + return [`koshien.object(${object})`]; + }; + return Generator; } diff --git a/src/lib/ruby-to-blocks-converter/koshien.js b/src/lib/ruby-to-blocks-converter/koshien.js index 2655b47d4ee..b35374bb4f7 100644 --- a/src/lib/ruby-to-blocks-converter/koshien.js +++ b/src/lib/ruby-to-blocks-converter/koshien.js @@ -66,6 +66,15 @@ const KoshienConverter = { const exceptCells = args[0].get('sym:except_cells'); const result = args[0].get('sym:result'); + if (!src && !dst && !exceptCells) { + if (!converter.isListBlock(result) && !converter.isNil(result)) return null; + + const block = converter.changeRubyExpressionBlock(receiver, 'koshien_calcGoalRoute', 'statement'); + converter.addField(block, 'RESULT', converter.lookupListFromListBlock(result)?.name || ' '); + converter.removeBlock(result); + return block; + } + if (!checkPosition(src)) return null; if (!checkPosition(dst)) return null; if (!converter.isListBlock(exceptCells) && !converter.isNil(exceptCells)) return null; @@ -138,12 +147,20 @@ const KoshienConverter = { const block = converter.changeRubyExpressionBlock(receiver, 'koshien_locateObjects', 'statement'); converter.addNumberInput(block, 'SQ_SIZE', 'math_number', sqSize, 0); converter.addTextInput(block, 'POSITION', cent, '0:0'); - converter.addTextInput(block, 'OBJECTS', objects, 'A B C D'); + converter.addTextInput(block, 'OBJECTS', objects, 'ABCD'); converter.addField(block, 'RESULT', converter.lookupListFromListBlock(result)?.name || ' '); converter.removeBlock(result); return block; }); + converter.registerCallMethod(Koshien, 'other_player', 0, params => { + const {receiver} = params; + const block = converter.changeRubyExpressionBlock(receiver, 'koshien_targetCoordinate', 'value'); + converter.addField(block, 'TARGET', 'other_player'); + converter.addField(block, 'COORDINATE', 'position'); + return block; + }); + converter.registerCallMethod(Koshien, 'other_player_x', 0, params => { const {receiver} = params; const block = converter.changeRubyExpressionBlock(receiver, 'koshien_targetCoordinate', 'value'); @@ -160,6 +177,14 @@ const KoshienConverter = { return block; }); + converter.registerCallMethod(Koshien, 'enemy', 0, params => { + const {receiver} = params; + const block = converter.changeRubyExpressionBlock(receiver, 'koshien_targetCoordinate', 'value'); + converter.addField(block, 'TARGET', 'enemy'); + converter.addField(block, 'COORDINATE', 'position'); + return block; + }); + converter.registerCallMethod(Koshien, 'enemy_x', 0, params => { const {receiver} = params; const block = converter.changeRubyExpressionBlock(receiver, 'koshien_targetCoordinate', 'value'); @@ -176,6 +201,14 @@ const KoshienConverter = { return block; }); + converter.registerCallMethod(Koshien, 'goal', 0, params => { + const {receiver} = params; + const block = converter.changeRubyExpressionBlock(receiver, 'koshien_targetCoordinate', 'value'); + converter.addField(block, 'TARGET', 'goal'); + converter.addField(block, 'COORDINATE', 'position'); + return block; + }); + converter.registerCallMethod(Koshien, 'goal_x', 0, params => { const {receiver} = params; const block = converter.changeRubyExpressionBlock(receiver, 'koshien_targetCoordinate', 'value'); @@ -192,6 +225,14 @@ const KoshienConverter = { return block; }); + converter.registerCallMethod(Koshien, 'player', 0, params => { + const {receiver} = params; + const block = converter.changeRubyExpressionBlock(receiver, 'koshien_targetCoordinate', 'value'); + converter.addField(block, 'TARGET', 'player'); + converter.addField(block, 'COORDINATE', 'position'); + return block; + }); + converter.registerCallMethod(Koshien, 'player_x', 0, params => { const {receiver} = params; const block = converter.changeRubyExpressionBlock(receiver, 'koshien_targetCoordinate', 'value'); @@ -252,6 +293,16 @@ const KoshienConverter = { converter.addField(block, 'COORDINATE', 'y'); return block; }); + + converter.registerCallMethod(Koshien, 'object', 1, params => { + const {receiver, args} = params; + + if (!converter.isString(args[0])) return null; + + const block = converter.changeRubyExpressionBlock(receiver, 'koshien_object', 'value'); + converter.addField(block, 'OBJECT', args[0]); + return block; + }); } }; diff --git a/test/integration/ruby-tab/extension_koshien.test.js b/test/integration/ruby-tab/extension_koshien.test.js index a43d794774b..8cc5a87c1a1 100644 --- a/test/integration/ruby-tab/extension_koshien.test.js +++ b/test/integration/ruby-tab/extension_koshien.test.js @@ -32,6 +32,7 @@ describe('Ruby Tab: Koshien extension blocks', () => { koshien.connect_game(name: "player1") koshien.get_map_area("0:1") koshien.move_to("2:3") + koshien.calc_route(result: list("$最短経路")) koshien.calc_route(result: list("$最短経路"), src: "4:5", dst: "6:7", except_cells: list("$通らない座標")) koshien.calc_route(result: nil, src: "4:5", dst: "6:7", except_cells: nil) koshien.set_dynamite("8:9") @@ -40,8 +41,8 @@ describe('Ruby Tab: Koshien extension blocks', () => { $すべてのマップ情報 = koshien.map_all $マップ情報 = koshien.map_from("14:0", $すべてのマップ情報) $マップ情報 = koshien.map_from("14:0", nil) - koshien.locate_objects(result: list("$地形・アイテム"), sq_size: 3, cent: "1:2", objects: "A B C D") - koshien.locate_objects(result: nil, sq_size: 3, cent: "1:2", objects: "A B C D") + koshien.locate_objects(result: list("$地形・アイテム"), sq_size: 3, cent: "1:2", objects: "ABCD") + koshien.locate_objects(result: nil, sq_size: 3, cent: "1:2", objects: "ABCD") koshien.turn_over koshien.position_of_x("0:1") @@ -50,22 +51,62 @@ describe('Ruby Tab: Koshien extension blocks', () => { koshien.position(4, 5) + koshien.player + koshien.player_x koshien.player_y + koshien.other_player + koshien.other_player_x koshien.other_player_y + koshien.goal + koshien.goal_x koshien.goal_y + koshien.enemy + koshien.enemy_x koshien.enemy_y + koshien.object("unknown") + + koshien.object("space") + + koshien.object("wall") + + koshien.object("storehouse") + + koshien.object("goal") + + koshien.object("water") + + koshien.object("breakable wall") + + koshien.object("tea") + + koshien.object("sweets") + + koshien.object("coin") + + koshien.object("dolphin") + + koshien.object("sword") + + koshien.object("poison") + + koshien.object("snake") + + koshien.object("trap") + + koshien.object("bomb") + `; await expectInterconvertBetweenCodeAndRuby(code); }); From c64b028bb9d61d92a5b9b5ddeb7a06a3f70bae63 Mon Sep 17 00:00:00 2001 From: Kouji Takao Date: Mon, 26 Aug 2024 16:13:33 +0900 Subject: [PATCH 2/2] feat: update scratch-vm --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index b123913af1d..30a9b961ad5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26933,7 +26933,7 @@ }, "node_modules/scratch-vm": { "version": "4.5.413", - "resolved": "git+ssh://git@github.com/smalruby/scratch-vm.git#30de145e492c1c3c77228e69eed1a0b1903729d5", + "resolved": "git+ssh://git@github.com/smalruby/scratch-vm.git#323d821a880adf74ef5e8649d22b7640a339220b", "license": "BSD-3-Clause", "dependencies": { "@vernier/godirect": "^1.5.0",