게시판오목 좌표 LoRA: 15×15와 19×19 격자를 정확히 읽히기예제 소스

예제 소스

오목 좌표 LoRA: 15×15와 19×19 격자를 정확히 읽히기 · 파일 59개

route.ts

import { NextResponse } from "next/server";
import { requestOmk3Move } from "@/lib/omk3Client";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";
export const maxDuration = 300;

type Body = {
  board?: number[];
  size?: number;
  ai_side?: number;
};

export async function POST(req: Request) {
  let body: Body;
  try {
    body = (await req.json()) as Body;
  } catch {
    return NextResponse.json({ type: "error", error: "invalid json" }, { status: 400 });
  }

  const board = body.board ?? [];
  const size = Number(body.size ?? 15);
  const aiSide = Number(body.ai_side ?? 2);
  if (aiSide !== 1 && aiSide !== 2) {
    return NextResponse.json({ type: "error", error: "ai_side must be 1 or 2" }, { status: 400 });
  }

  if (![13, 15, 19].includes(size)) {
    return NextResponse.json(
      { type: "error", error: `unsupported size: ${size}` },
      { status: 400 },
    );
  }
  if (board.length !== size * size) {
    return NextResponse.json(
      { type: "error", error: `board length must be ${size * size}` },
      { status: 400 },
    );
  }

  const result = await requestOmk3Move({
    board,
    size,
    aiSide: aiSide as 1 | 2,
  });

  if (!result.ok) {
    const msg = result.error;
    const unavailable =
      /연결 실패|ECONNREFUSED|시간 초과|timeout|게이트웨이/i.test(msg);
    return NextResponse.json(
      { type: "error", error: msg },
      { status: unavailable ? 503 : 502 },
    );
  }
  return NextResponse.json({ type: "move", row: result.row, col: result.col });
}