Сравнение кода от DeepSeek и ChatGPT

—

от автора

Без лишних предисловий — давайте сделаем два абсолютно одинаковых запроса для создания приложения на SwiftUI и сравним, какая модель лучше справится с этими задачами.

Я решила дать два задания. Начнём с первого: нужно написать игру «Змейка», вот мой промпт:

Напиши полностью с нуля приложение на SwiftUI. В приложении должен быть один экран. Сделай простейший вариант игры змейка. Изначально зеленая змея из 3-х кваратиков, по мере съедания квадратика она увеличивается на 1 квадрат (квадратики которые она съедает — разных цветов)

Если лень читать — в конце ссылка на короткое видео сравнения (в телеграм канале).

Посмотрим, что нам выдал ChatGPT:

Ответ ChatGPT

Вот готовый код для простейшей игры «Змейка» на SwiftUI. Змея стартует с длиной в 3 квадрата и растёт при поедании еды разного цвета. Управление происходит свайпами.

import SwiftUI  struct SnakeGameView: View {     @State private var snake: [CGPoint] = [CGPoint(x: 100, y: 100), CGPoint(x: 80, y: 100), CGPoint(x: 60, y: 100)]     @State private var food: CGPoint = CGPoint(x: 200, y: 200)     @State private var direction: CGPoint = CGPoint(x: 20, y: 0)     @State private var timer = Timer.publish(every: 0.2, on: .main, in: .common).autoconnect()          let gridSize: CGFloat = 20     let colors: [Color] = [.red, .blue, .yellow, .purple, .orange]          var body: some View {         ZStack {             Color.black.ignoresSafeArea()                          ForEach(snake.indices, id: \..self) { index in                 Rectangle()                     .fill(Color.green)                     .frame(width: gridSize, height: gridSize)                     .position(snake[index])             }                          Rectangle()                 .fill(colors.randomElement()!)                 .frame(width: gridSize, height: gridSize)                 .position(food)         }         .gesture(DragGesture()             .onEnded { gesture in                 let xMove = gesture.translation.width                 let yMove = gesture.translation.height                                  if abs(xMove) > abs(yMove) {                     direction = xMove > 0 ? CGPoint(x: gridSize, y: 0) : CGPoint(x: -gridSize, y: 0)                 } else {                     direction = yMove > 0 ? CGPoint(x: 0, y: gridSize) : CGPoint(x: 0, y: -gridSize)                 }             }         )         .onReceive(timer) { _ in             moveSnake()         }     }          private func moveSnake() {         var newHead = snake.first!         newHead.x += direction.x         newHead.y += direction.y                  if newHead == food {             snake.insert(newHead, at: 0)             food = generateNewFood()         } else {             snake.insert(newHead, at: 0)             snake.removeLast()         }     }          private func generateNewFood() -> CGPoint {         let x = CGFloat(Int.random(in: 0..<Int(UIScreen.main.bounds.width / gridSize))) * gridSize         let y = CGFloat(Int.random(in: 0..<Int(UIScreen.main.bounds.height / gridSize))) * gridSize         return CGPoint(x: x, y: y)     } }  struct ContentView: View {     var body: some View {         SnakeGameView()     } }  @main struct SnakeGameApp: App {     var body: some Scene {         WindowGroup {             ContentView()         }     } }

Этот код создаёт простейшую змейку, которая управляется свайпами. Когда змея съедает еду, она увеличивается в длине, а еда появляется в новом случайном месте и меняет цвет. Игра бесконечна, но можно добавить столкновение с границами или самой собой для усложнения. 🚀

И вот что мы получили:

ChatGPT змейка

ChatGPT змейка

В целом, всё максимально соответствует описанию, код работает с первого раза. Есть недочеты, что змейка может уйти за пределы экрана, например. Но для базы сойдёт.

Дальше такой же промпт вставляем в DeepSeek, вот что получаем:

Ответ DeepSeek

Создадим простейшую версию игры «Змейка» на SwiftUI. В этом приложении будет один экран, на котором змейка будет двигаться по экрану и «съедать» квадратики, увеличиваясь в длину.

Шаги для создания приложения:

  1. Создадим структуру для змейки и еды.

  2. Реализуем логику движения змейки.

  3. Добавим обработку касаний для управления змейкой.

  4. Отрисуем змейку и еду на экране.

Полный код приложения:

import SwiftUI  struct ContentView: View {     @State private var snake: [CGPoint] = [         CGPoint(x: 100, y: 100),         CGPoint(x: 90, y: 100),         CGPoint(x: 80, y: 100)     ]     @State private var food: CGPoint = CGPoint(x: 200, y: 200)     @State private var direction: CGPoint = CGPoint(x: 10, y: 0)     @State private var foodColor: Color = .red     @State private var score: Int = 0          let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()          var body: some View {         ZStack {             Color.black.edgesIgnoringSafeArea(.all)                          // Рисуем змейку             ForEach(snake, id: \.self) { segment in                 Rectangle()                     .fill(Color.green)                     .frame(width: 10, height: 10)                     .position(segment)             }                          // Рисуем еду             Rectangle()                 .fill(foodColor)                 .frame(width: 10, height: 10)                 .position(food)                          // Отображаем счет             Text("Score: \(score)")                 .foregroundColor(.white)                 .font(.largeTitle)                 .padding()         }         .onReceive(timer) { _ in             moveSnake()         }         .gesture(             DragGesture()                 .onEnded { gesture in                     let delta = gesture.translation                     if abs(delta.width) > abs(delta.height) {                         // Горизонтальный свайп                         if delta.width > 0 {                             direction = CGPoint(x: 10, y: 0) // Вправо                         } else {                             direction = CGPoint(x: -10, y: 0) // Влево                         }                     } else {                         // Вертикальный свайп                         if delta.height > 0 {                             direction = CGPoint(x: 0, y: 10) // Вниз                         } else {                             direction = CGPoint(x: 0, y: -10) // Вверх                         }                     }                 }         )     }          func moveSnake() {         var newSnake = snake         let head = newSnake[0]                  // Новое положение головы         let newHead = CGPoint(x: head.x + direction.x, y: head.y + direction.y)                  // Проверяем, съела ли змейка еду         if abs(newHead.x - food.x) < 10 && abs(newHead.y - food.y) < 10 {             score += 1             generateFood()         } else {             newSnake.removeLast()         }                  newSnake.insert(newHead, at: 0)         snake = newSnake     }          func generateFood() {         let maxX = UIScreen.main.bounds.width - 10         let maxY = UIScreen.main.bounds.height - 10                  food = CGPoint(             x: CGFloat.random(in: 0...maxX),             y: CGFloat.random(in: 0...maxY)         )                  foodColor = Color(             red: Double.random(in: 0...1),             green: Double.random(in: 0...1),             blue: Double.random(in: 0...1)         )     } }  @main struct SnakeApp: App {     var body: some Scene {         WindowGroup {             ContentView()         }     } }

Описание кода:

  1. Змейка и еда:

    • Змейка представлена массивом CGPoint, где каждый элемент — это координата одного сегмента змейки.

    • Еда — это случайная точка на экране, которая меняет цвет при каждом появлении.

  2. Движение змейки:

    • Змейка движется с постоянной скоростью, обновляя свое положение каждые 0.1 секунды.

    • Если змейка «съедает» еду, ее длина увеличивается на один сегмент, и генерируется новая еда.

  3. Управление:

    • Если пользователь свайпает вправо, змейка поворачивает вправо.

    • Если пользователь свайпает влево, змейка поворачивает влево.

    • Аналогично для свайпов вверх и вниз.

  4. Отрисовка:

    • Змейка и еда отрисовываются с помощью Rectangle в SwiftUI.

Как запустить:

  1. Создайте новый проект в Xcode с использованием SwiftUI.

  2. Замените содержимое файла ContentView.swift на приведенный выше код.

  3. Запустите приложение на симуляторе или устройстве.

Теперь у вас есть простая версия игры «Змейка» на SwiftUI!

DeepSeek змейка

DeepSeek змейка

Что тут интересного: змейка по размерам сильно меньше, скорость чуть выше. При изначально одинаковом запросе, DeepSeek добавил от себя лейбл с подсчётом очков. Так же проблема с тем, что змейка уходит за рамки экрана и не возвращается.

И кстати, я нигде не указывала, каким должно быть управление и по умолчанию обе модели сделали управление по свайпу (это логично, но с другой стороны, вариантов много: стрелочки, гироскоп и пр.)

Считаю что с первым заданием обе модели справились. Счёт 1:1.

Далее в преддверии 14 февраля в голову ударили сердечки, поэтому попросила сделать обе модели простенькую анимацию. Вот такой был промпт:

Напиши полностью с нуля приложение на SwiftUI. В приложении должен быть один экран. На нём на тёмном фоне должна быть такая анимация:

Сердечки плавно падают сверху экрана, но при клике по экрану они разлетаются в стороны. Выглядит ярко и визуально привлекательно.

Сердечки должны быть разных оттенков розового и разного размера.

Начнём с ChatGPT. Вот результат:

Ответ ChatGPT

Вот полный код приложения на SwiftUI, которое реализует эффект падающих сердечек с разлетом при клике.

Что делает этот код?

• Сердечки падают сверху экрана с разной скоростью и размером.

• Клик по экрану заставляет сердечки разлететься в стороны.

• Разные оттенки розового и размеры сердечек делают анимацию визуально привлекательной.

import SwiftUI  struct Heart: Identifiable {     let id = UUID()     var position: CGPoint     var size: CGFloat     var color: Color     var velocity: CGFloat }  struct ContentView: View {     @State private var hearts: [Heart] = []     @State private var explode = false     let screenWidth = UIScreen.main.bounds.width     let screenHeight = UIScreen.main.bounds.height      var body: some View {         ZStack {             Color.black.ignoresSafeArea()              ForEach(hearts) { heart in                 HeartShape()                     .fill(heart.color)                     .frame(width: heart.size, height: heart.size)                     .position(heart.position)                     .opacity(explode ? 0.5 : 1)                     .animation(.easeInOut(duration: 1.5), value: explode)             }         }         .onAppear {             startDroppingHearts()         }         .onTapGesture {             explodeHearts()         }     }      func startDroppingHearts() {         Timer.scheduledTimer(withTimeInterval: 0.3, repeats: true) { timer in             let newHeart = Heart(                 position: CGPoint(x: CGFloat.random(in: 0...screenWidth), y: -50),                 size: CGFloat.random(in: 20...50),                 color: Color(red: Double.random(in: 0.8...1), green: Double.random(in: 0...0.3), blue: Double.random(in: 0.5...0.7)),                 velocity: CGFloat.random(in: 2...5)             )              hearts.append(newHeart)              withAnimation(.linear(duration: 3)) {                 for index in hearts.indices {                     hearts[index].position.y += screenHeight + 50                 }             }              hearts.removeAll { $0.position.y > screenHeight + 50 }         }     }      func explodeHearts() {         explode = true         withAnimation(.easeOut(duration: 0.5)) {             for index in hearts.indices {                 hearts[index].position.x += CGFloat.random(in: -100...100)                 hearts[index].position.y += CGFloat.random(in: -100...100)             }         }          DispatchQueue.main.asyncAfter(deadline: .now() + 0.7) {             explode = false         }     } }  struct HeartShape: Shape {     func path(in rect: CGRect) -> Path {         var path = Path()          let width = rect.width         let height = rect.height          path.move(to: CGPoint(x: width / 2, y: height))         path.addCurve(to: CGPoint(x: 0, y: height / 3),                       control1: CGPoint(x: width * 0.3, y: height * 1.1),                       control2: CGPoint(x: 0, y: height * 0.6))          path.addArc(center: CGPoint(x: width * 0.25, y: height / 3),                     radius: width * 0.25,                     startAngle: .degrees(180),                     endAngle: .degrees(0),                     clockwise: false)          path.addArc(center: CGPoint(x: width * 0.75, y: height / 3),                     radius: width * 0.25,                     startAngle: .degrees(180),                     endAngle: .degrees(0),                     clockwise: false)          path.addCurve(to: CGPoint(x: width / 2, y: height),                       control1: CGPoint(x: width, y: height * 0.6),                       control2: CGPoint(x: width * 0.7, y: height * 1.1))          return path     } }  @main struct HeartsApp: App {     var body: some Scene {         WindowGroup {             ContentView()         }     } }

Как это работает?

• Падающие сердечки создаются каждые 0.3 секунды и плавно движутся вниз.

• Сердечки разного размера и оттенка розового.

• При клике по экрану сердечки разлетаются в случайном направлении.

• Анимации делают разлет плавным и красивым.

Попробуй запустить этот код в Xcode, и ты увидишь магию 💖✨!

ChatCPT попытка 1

ChatCPT попытка 1

Получилась какая-то хрень. Но я решила дать ему ещё один шанс и попросила исправить, чтобы сердечки падали на весь экран.

Со второго раза:

ChatCPT попытка 2

ChatCPT попытка 2

Нуууу, почти. Сердечки падают, они разного цвета и размера. При нажатии происходит «улёт» вниз и дальше опять глюк, что они только в первой четверти экрана появляются.

В целом ок, с учётом того, что код я не смотрела вообще.

Теперь посмотрим ответ от DeepSeek

Ответ DeepSeek

Создадим приложение на SwiftUI с анимацией падающих сердечек, которые разлетаются при нажатии на экран. Вот полный код:

import SwiftUI  struct Heart: Identifiable {     let id = UUID()     var position: CGPoint     var color: Color     var size: CGFloat     var isFlying: Bool = false }  struct ContentView: View {     @State private var hearts: [Heart] = []     @State private var timer: Timer?          var body: some View {         ZStack {             Color.black                 .edgesIgnoringSafeArea(.all)                          ForEach(hearts) { heart in                 Image(systemName: "heart.fill")                     .font(.system(size: heart.size))                     .foregroundColor(heart.color)                     .position(heart.position)                     .animation(.linear(duration: heart.isFlying ? 0.5 : 10), value: heart.position)             }         }         .onAppear {             startHeartsAnimation()         }         .onDisappear {             timer?.invalidate()         }         .onTapGesture {             explodeHearts()         }     }          private func startHeartsAnimation() {         timer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { _ in             let size = CGFloat.random(in: 20...50)             let heart = Heart(                 position: CGPoint(x: CGFloat.random(in: 0...UIScreen.main.bounds.width), y: -size),                 color: Color(red: Double.random(in: 0.7...1), green: Double.random(in: 0.2...0.5), blue: Double.random(in: 0.4...0.7)),                 size: size             )             hearts.append(heart)                          DispatchQueue.main.asyncAfter(deadline: .now() + 10) {                 if let index = hearts.firstIndex(where: { $0.id == heart.id }) {                     hearts.remove(at: index)                 }             }                          withAnimation(.linear(duration: 10)) {                 if let index = hearts.firstIndex(where: { $0.id == heart.id }) {                     hearts[index].position.y = UIScreen.main.bounds.height + size                 }             }         }     }          private func explodeHearts() {         for index in hearts.indices {             let angle = Double.random(in: 0..<2 * .pi)             let distance = CGFloat.random(in: 100...300)             let newX = hearts[index].position.x + cos(angle) * distance             let newY = hearts[index].position.y + sin(angle) * distance                          withAnimation(.easeOut(duration: 0.5)) {                 hearts[index].position = CGPoint(x: newX, y: newY)                 hearts[index].isFlying = true             }                          DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {                 if let index = hearts.firstIndex(where: { $0.id == hearts[index].id }) {                     hearts.remove(at: index)                 }             }         }     } }  @main struct HeartAnimationApp: App {     var body: some Scene {         WindowGroup {             ContentView()         }     } }

DeepSeek сердечки

DeepSeek сердечки

DeepSeek с первого раза выдал довольно пристойную реализацию. Максимально соответствует запросу.

Единственный минус, что после того как я нажимаю на экран и сердечки разлетаются — превью крашится.

Я считаю, что во второй задаче победил DeepSeek. К моему удивлению, я была скептически настроена, но посмотрев и сравнив их на практике — кажется, что DeepSeek вообще ничем не уступает ChatGPT, по крайней мере в написании кода. И ещё надо учитывать то, что DeepSeek работает бесплатно и без ВПН и для регистрации мне не потребовалось ничего, кроме почты.

Кто ещё тестировал на других языках, пишите как вам?

Ссылка на телеграм канал с видео.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Как считаете, какая нейросеть справилась лучше

9.7% ChatGPT35
90.3% DeepSeek326

Проголосовал 361 пользователь. Воздержались 133 пользователя.

ссылка на оригинал статьи https://habr.com/ru/articles/878060/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *