With[{r=RandomInteger[{1,6}],(*ピースの組み合わせをランダムに決定する*)
(*それぞれのピースの形*)
shapes=
<|
1->{{0,0},{0,1},{0,2},{1,2}},(*J字型ピース*)
2->{{0,1},{1,0},{1,1},{2,1}},(*T字型ピース1*)
3->{{0,1},{1,0},{1,1},{2,1}},(*T字型ピース2*)
4->{{0,0},{0,1},{0,2},{0,3}},(*I字型ピース*)
5->{{0,0},{0,1},{1,1},{1,0}},(*O字型ピース*)
6->{{0,0},{1,0},{2,0},{2,1}},(*L字型ピース*)
7->{{0,1},{1,1},{1,0},{2,0}},(*Z字型ピース*)
8->{{0,0},{1,0},{1,1},{2,1}}(*S字型ピース*)
|>,

(*それぞれのピースの色*)
colors=
<|
1->Blue,
2->Purple,
3->Magenta,
4->Cyan,
5->Yellow,
6->Orange,
7->Red,
8->Green
|>,

(*それぞれのピースの名前*)
name=
<|
1->"J",
2->"T1",
3->"T2",
4->"I",
5->"O",
6->"L",
7->"Z",
8->"S"
|>,

(*4×4が埋まるピースの組み合わせ*)
randomPiece=
{
{1,2,3,4},
{1,4,5,6},
{1,4,6,7},
{1,4,6,8},
{2,3,6,7},
{1,2,3,8}
}
},
Module[{pShapes,pColors,piecename},
(*決定したピースの組み合わせの形*)
pShapes=
<|
1->shapes[randomPiece[[r,1]]],
2->shapes[randomPiece[[r,2]]],
3->shapes[randomPiece[[r,3]]],
4->shapes[randomPiece[[r,4]]]
|>;

(*決定したピースの組み合わせの色*)
pColors=
<|
1->colors[randomPiece[[r,1]]],
2->colors[randomPiece[[r,2]]],
3->colors[randomPiece[[r,3]]],
4->colors[randomPiece[[r,4]]]
|>;

(*決定したピースの組み合わせの名前*)
piecename=
<|
1->name[randomPiece[[r,1]]],
2->name[randomPiece[[r,2]]],
3->name[randomPiece[[r,3]]],
4->name[randomPiece[[r,4]]]
|>;
DynamicModule[
{
x=0,y=0,(*ピースの初期位置*)

pieceShapes=pShapes,
pieceColors=pColors,

angleIndex=1,(*回転状態のインデックス：1〜4*)
angles={0,Pi/2,Pi,3Pi/2} ,(*回転角度のリスト*)
radians=0,
board=<|1->Null,2->Null,3->Null,4->Null|>,(*配置済みピースの位置*)
rot=<|1->Null,2->Null,3->Null,4->Null|>,(*配置済みピースの回転状態*)
piece=1(*最初に表示されるピース*)
},
Column[
{
Dynamic[
Graphics[
{
EdgeForm[Black],

(*4x4 のパズル台*)
Table[
{FaceForm[White],
Rectangle[{i,j},{i+1,j+1}]},{i,0,3},{j,0,3}
],

(*動的なピース描画*)
{Opacity[0.2],(*操作中のピースは半透明*)
pieceColors[piece],
(*回転適用*)
Module[
{rotatedPiece},
radians=angles[[angleIndex]] ;
rotatedPiece=Round[RotationTransform[radians,{0,0}]/@pieceShapes[piece]];
(*描画*)
Rectangle[{x,y}+#,{x,y}+#+{1,1}]&/@rotatedPiece]
},

(*配置済みピースを描画*)
Table[
If[board[[i]]=!=Null,
{pieceColors[i],
Module[
{rotatedPiece},
rotatedPiece=Round[RotationTransform[rot[[i]],{0,0}]/@pieceShapes[i]];
(*描画*)
Rectangle[board[[i]]+#,board[[i]]+#+{1,1}]&/@rotatedPiece]
}
]
,{i,1,4}
]
},
PlotRange->{{-3,7},{-3,7}},ImageSize->300,AspectRatio->1
]
],
Row[
(*ピースごとに適切なボタンを作成*)
Table[
With[{n=i},
Button[piecename[n],piece=n,ImageSize->{100,30}]
],
{i,1,4}
],
Spacer[10](*ボタン同士の間隔*)
],
Row[{
(*ピースの位置*)
"X: ",Slider[Dynamic[x],{0,3,1}],
Spacer[20],
"Y: ",Slider[Dynamic[y],{0,3,1}]
}],
Button["配置",{board[[piece]]={x,y},rot[[piece]]=radians}],
Button["回転",angleIndex=Mod[angleIndex,4]+1],
Button["リセット",
{board=<|1->Null,2->Null,3->Null,4->Null|>,
rot=<|1->Null,2->Null,3->Null,4->Null|>}
]
}
]
]
]
]